src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java

Thu, 29 Aug 2013 11:41:20 -0700

author
jjg
date
Thu, 29 Aug 2013 11:41:20 -0700
changeset 1985
0e6577980181
parent 1568
5f0731e4e5e6
child 2023
cf37c3775397
permissions
-rw-r--r--

8001669: javadoc internal DocletAbortException should set cause when appropriate
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 1997, 2013, 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  */
    25 package com.sun.tools.doclets.formats.html;
    27 import java.io.*;
    28 import java.util.*;
    30 import com.sun.javadoc.*;
    31 import com.sun.tools.javac.sym.Profiles;
    32 import com.sun.tools.javac.jvm.Profile;
    33 import com.sun.tools.doclets.internal.toolkit.*;
    34 import com.sun.tools.doclets.internal.toolkit.builders.*;
    35 import com.sun.tools.doclets.internal.toolkit.util.*;
    37 /**
    38  * The class with "start" method, calls individual Writers.
    39  *
    40  *  <p><b>This is NOT part of any supported API.
    41  *  If you write code that depends on this, you do so at your own risk.
    42  *  This code and its internal interfaces are subject to change or
    43  *  deletion without notice.</b>
    44  *
    45  * @author Atul M Dambalkar
    46  * @author Robert Field
    47  * @author Jamie Ho
    48  *
    49  */
    50 public class HtmlDoclet extends AbstractDoclet {
    51     // An instance will be created by validOptions, and used by start.
    52     private static HtmlDoclet docletToStart = null;
    54     public HtmlDoclet() {
    55         configuration = new ConfigurationImpl();
    56     }
    58     /**
    59      * The global configuration information for this run.
    60      */
    61     public final ConfigurationImpl configuration;
    63     /**
    64      * The "start" method as required by Javadoc.
    65      *
    66      * @param root the root of the documentation tree.
    67      * @see com.sun.javadoc.RootDoc
    68      * @return true if the doclet ran without encountering any errors.
    69      */
    70     public static boolean start(RootDoc root) {
    71         // In typical use, options will have been set up by calling validOptions,
    72         // which will create an HtmlDoclet for use here.
    73         HtmlDoclet doclet;
    74         if (docletToStart != null) {
    75             doclet = docletToStart;
    76             docletToStart = null;
    77         } else {
    78             doclet = new HtmlDoclet();
    79         }
    80         return doclet.start(doclet, root);
    81     }
    83     /**
    84      * Create the configuration instance.
    85      * Override this method to use a different
    86      * configuration.
    87      */
    88     public Configuration configuration() {
    89         return configuration;
    90     }
    92     /**
    93      * Start the generation of files. Call generate methods in the individual
    94      * writers, which will in turn genrate the documentation files. Call the
    95      * TreeWriter generation first to ensure the Class Hierarchy is built
    96      * first and then can be used in the later generation.
    97      *
    98      * For new format.
    99      *
   100      * @see com.sun.javadoc.RootDoc
   101      */
   102     protected void generateOtherFiles(RootDoc root, ClassTree classtree)
   103             throws Exception {
   104         super.generateOtherFiles(root, classtree);
   105         if (configuration.linksource) {
   106             SourceToHTMLConverter.convertRoot(configuration,
   107                 root, DocPaths.SOURCE_OUTPUT);
   108         }
   110         if (configuration.topFile.isEmpty()) {
   111             configuration.standardmessage.
   112                 error("doclet.No_Non_Deprecated_Classes_To_Document");
   113             return;
   114         }
   115         boolean nodeprecated = configuration.nodeprecated;
   116         performCopy(configuration.helpfile);
   117         performCopy(configuration.stylesheetfile);
   118         copyResourceFile("background.gif");
   119         copyResourceFile("tab.gif");
   120         copyResourceFile("titlebar.gif");
   121         copyResourceFile("titlebar_end.gif");
   122         copyResourceFile("activetitlebar.gif");
   123         copyResourceFile("activetitlebar_end.gif");
   124         // do early to reduce memory footprint
   125         if (configuration.classuse) {
   126             ClassUseWriter.generate(configuration, classtree);
   127         }
   128         IndexBuilder indexbuilder = new IndexBuilder(configuration, nodeprecated);
   130         if (configuration.createtree) {
   131             TreeWriter.generate(configuration, classtree);
   132         }
   133         if (configuration.createindex) {
   134             if (configuration.splitindex) {
   135                 SplitIndexWriter.generate(configuration, indexbuilder);
   136             } else {
   137                 SingleIndexWriter.generate(configuration, indexbuilder);
   138             }
   139         }
   141         if (!(configuration.nodeprecatedlist || nodeprecated)) {
   142             DeprecatedListWriter.generate(configuration);
   143         }
   145         AllClassesFrameWriter.generate(configuration,
   146             new IndexBuilder(configuration, nodeprecated, true));
   148         FrameOutputWriter.generate(configuration);
   150         if (configuration.createoverview) {
   151             PackageIndexWriter.generate(configuration);
   152         }
   153         if (configuration.helpfile.length() == 0 &&
   154             !configuration.nohelp) {
   155             HelpWriter.generate(configuration);
   156         }
   157         // If a stylesheet file is not specified, copy the default stylesheet
   158         // and replace newline with platform-specific newline.
   159         DocFile f;
   160         if (configuration.stylesheetfile.length() == 0) {
   161             f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
   162             f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
   163         }
   164         f = DocFile.createFileForOutput(configuration, DocPaths.JAVASCRIPT);
   165         f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.JAVASCRIPT), true, true);
   166     }
   168     /**
   169      * {@inheritDoc}
   170      */
   171     protected void generateClassFiles(ClassDoc[] arr, ClassTree classtree) {
   172         Arrays.sort(arr);
   173         for(int i = 0; i < arr.length; i++) {
   174             if (!(configuration.isGeneratedDoc(arr[i]) && arr[i].isIncluded())) {
   175                 continue;
   176             }
   177             ClassDoc prev = (i == 0)?
   178                 null:
   179                 arr[i-1];
   180             ClassDoc curr = arr[i];
   181             ClassDoc next = (i+1 == arr.length)?
   182                 null:
   183                 arr[i+1];
   184             try {
   185                 if (curr.isAnnotationType()) {
   186                     AbstractBuilder annotationTypeBuilder =
   187                         configuration.getBuilderFactory()
   188                             .getAnnotationTypeBuilder((AnnotationTypeDoc) curr,
   189                                 prev, next);
   190                     annotationTypeBuilder.build();
   191                 } else {
   192                     AbstractBuilder classBuilder =
   193                         configuration.getBuilderFactory()
   194                             .getClassBuilder(curr, prev, next, classtree);
   195                     classBuilder.build();
   196                 }
   197             } catch (Exception e) {
   198                 e.printStackTrace();
   199                 throw new DocletAbortException(e);
   200             }
   201         }
   202     }
   204     /**
   205      * {@inheritDoc}
   206      */
   207     protected void generateProfileFiles() throws Exception {
   208         if (configuration.showProfiles) {
   209             ProfileIndexFrameWriter.generate(configuration);
   210             Profile prevProfile = null, nextProfile;
   211             for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
   212                 ProfilePackageIndexFrameWriter.generate(configuration, Profile.lookup(i).name);
   213                 PackageDoc[] packages = configuration.profilePackages.get(
   214                         Profile.lookup(i).name);
   215                 PackageDoc prev = null, next;
   216                 for (int j = 0; j < packages.length; j++) {
   217                     // if -nodeprecated option is set and the package is marked as
   218                     // deprecated, do not generate the profilename-package-summary.html
   219                     // and profilename-package-frame.html pages for that package.
   220                     if (!(configuration.nodeprecated && Util.isDeprecated(packages[j]))) {
   221                         ProfilePackageFrameWriter.generate(configuration, packages[j], i);
   222                         next = (j + 1 < packages.length
   223                                 && packages[j + 1].name().length() > 0) ? packages[j + 1] : null;
   224                         AbstractBuilder profilePackageSummaryBuilder =
   225                                 configuration.getBuilderFactory().getProfilePackageSummaryBuilder(
   226                                 packages[j], prev, next, Profile.lookup(i));
   227                         profilePackageSummaryBuilder.build();
   228                         prev = packages[j];
   229                     }
   230                 }
   231                 nextProfile = (i + 1 < configuration.profiles.getProfileCount()) ?
   232                         Profile.lookup(i + 1) : null;
   233                 AbstractBuilder profileSummaryBuilder =
   234                         configuration.getBuilderFactory().getProfileSummaryBuilder(
   235                         Profile.lookup(i), prevProfile, nextProfile);
   236                 profileSummaryBuilder.build();
   237                 prevProfile = Profile.lookup(i);
   238             }
   239         }
   240     }
   242     /**
   243      * {@inheritDoc}
   244      */
   245     protected void generatePackageFiles(ClassTree classtree) throws Exception {
   246         PackageDoc[] packages = configuration.packages;
   247         if (packages.length > 1) {
   248             PackageIndexFrameWriter.generate(configuration);
   249         }
   250         PackageDoc prev = null, next;
   251         for (int i = 0; i < packages.length; i++) {
   252             // if -nodeprecated option is set and the package is marked as
   253             // deprecated, do not generate the package-summary.html, package-frame.html
   254             // and package-tree.html pages for that package.
   255             if (!(configuration.nodeprecated && Util.isDeprecated(packages[i]))) {
   256                 PackageFrameWriter.generate(configuration, packages[i]);
   257                 next = (i + 1 < packages.length &&
   258                         packages[i + 1].name().length() > 0) ? packages[i + 1] : null;
   259                 //If the next package is unnamed package, skip 2 ahead if possible
   260                 next = (i + 2 < packages.length && next == null) ? packages[i + 2] : next;
   261                 AbstractBuilder packageSummaryBuilder =
   262                         configuration.getBuilderFactory().getPackageSummaryBuilder(
   263                         packages[i], prev, next);
   264                 packageSummaryBuilder.build();
   265                 if (configuration.createtree) {
   266                     PackageTreeWriter.generate(configuration,
   267                             packages[i], prev, next,
   268                             configuration.nodeprecated);
   269                 }
   270                 prev = packages[i];
   271             }
   272         }
   273     }
   275     public static final ConfigurationImpl sharedInstanceForOptions =
   276             new ConfigurationImpl();
   278     /**
   279      * Check for doclet added options here.
   280      *
   281      * @return number of arguments to option. Zero return means
   282      * option not known.  Negative value means error occurred.
   283      */
   284     public static int optionLength(String option) {
   285         // Construct temporary configuration for check
   286         return sharedInstanceForOptions.optionLength(option);
   287     }
   289     /**
   290      * Check that options have the correct arguments here.
   291      * <P>
   292      * This method is not required and will default gracefully
   293      * (to true) if absent.
   294      * <P>
   295      * Printing option related error messages (using the provided
   296      * DocErrorReporter) is the responsibility of this method.
   297      *
   298      * @return true if the options are valid.
   299      */
   300     public static boolean validOptions(String options[][],
   301             DocErrorReporter reporter) {
   302         docletToStart = new HtmlDoclet();
   303         return docletToStart.configuration.validOptions(options, reporter);
   304     }
   306     /**
   307      * Copy a file in the resources directory to the destination directory.
   308      * @param resource   The name of the resource file to copy
   309      */
   310     private void copyResourceFile(String resource) {
   311         DocPath p = DocPaths.RESOURCES.resolve(resource);
   312         DocFile f = DocFile.createFileForOutput(configuration, p);
   313         f.copyResource(p, false, false);
   314     }
   316     private void performCopy(String filename) {
   317         if (filename.isEmpty())
   318             return;
   320         try {
   321             DocFile fromfile = DocFile.createFileForInput(configuration, filename);
   322             DocPath path = DocPath.create(fromfile.getName());
   323             DocFile toFile = DocFile.createFileForOutput(configuration, path);
   324             if (toFile.isSameFile(fromfile))
   325                 return;
   327             configuration.message.notice((SourcePosition) null,
   328                     "doclet.Copying_File_0_To_File_1",
   329                     fromfile.toString(), path.getPath());
   330             toFile.copyFile(fromfile);
   331         } catch (IOException exc) {
   332             configuration.message.error((SourcePosition) null,
   333                     "doclet.perform_copy_exception_encountered",
   334                     exc.toString());
   335             throw new DocletAbortException(exc);
   336         }
   337     }
   338 }

mercurial