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

Thu, 24 May 2018 18:02:46 +0800

author
aoqi
date
Thu, 24 May 2018 18:02:46 +0800
changeset 3446
e468915bad3a
parent 3315
6f0746b6de9f
parent 2525
2eb010b6cb22
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
aefimov@3315 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25 package com.sun.tools.doclets.formats.html;
aoqi@0 26
aoqi@0 27 import java.io.*;
aoqi@0 28 import java.util.*;
aoqi@0 29
aoqi@0 30 import com.sun.javadoc.*;
aoqi@0 31 import com.sun.tools.javac.sym.Profiles;
aoqi@0 32 import com.sun.tools.javac.jvm.Profile;
aoqi@0 33 import com.sun.tools.doclets.internal.toolkit.*;
aoqi@0 34 import com.sun.tools.doclets.internal.toolkit.builders.*;
aoqi@0 35 import com.sun.tools.doclets.internal.toolkit.util.*;
aoqi@0 36
aoqi@0 37 /**
aoqi@0 38 * The class with "start" method, calls individual Writers.
aoqi@0 39 *
aoqi@0 40 * <p><b>This is NOT part of any supported API.
aoqi@0 41 * If you write code that depends on this, you do so at your own risk.
aoqi@0 42 * This code and its internal interfaces are subject to change or
aoqi@0 43 * deletion without notice.</b>
aoqi@0 44 *
aoqi@0 45 * @author Atul M Dambalkar
aoqi@0 46 * @author Robert Field
aoqi@0 47 * @author Jamie Ho
aoqi@0 48 *
aoqi@0 49 */
aoqi@0 50 public class HtmlDoclet extends AbstractDoclet {
aoqi@0 51 // An instance will be created by validOptions, and used by start.
aoqi@0 52 private static HtmlDoclet docletToStart = null;
aoqi@0 53
aoqi@0 54 public HtmlDoclet() {
aoqi@0 55 configuration = new ConfigurationImpl();
aoqi@0 56 }
aoqi@0 57
aoqi@0 58 /**
aoqi@0 59 * The global configuration information for this run.
aoqi@0 60 */
aoqi@0 61 public final ConfigurationImpl configuration;
aoqi@0 62
aoqi@0 63 /**
aoqi@0 64 * The "start" method as required by Javadoc.
aoqi@0 65 *
aoqi@0 66 * @param root the root of the documentation tree.
aoqi@0 67 * @see com.sun.javadoc.RootDoc
aoqi@0 68 * @return true if the doclet ran without encountering any errors.
aoqi@0 69 */
aoqi@0 70 public static boolean start(RootDoc root) {
aoqi@0 71 // In typical use, options will have been set up by calling validOptions,
aoqi@0 72 // which will create an HtmlDoclet for use here.
aoqi@0 73 HtmlDoclet doclet;
aoqi@0 74 if (docletToStart != null) {
aoqi@0 75 doclet = docletToStart;
aoqi@0 76 docletToStart = null;
aoqi@0 77 } else {
aoqi@0 78 doclet = new HtmlDoclet();
aoqi@0 79 }
aoqi@0 80 return doclet.start(doclet, root);
aoqi@0 81 }
aoqi@0 82
aoqi@0 83 /**
aoqi@0 84 * Create the configuration instance.
aoqi@0 85 * Override this method to use a different
aoqi@0 86 * configuration.
aoqi@0 87 */
aoqi@0 88 public Configuration configuration() {
aoqi@0 89 return configuration;
aoqi@0 90 }
aoqi@0 91
aoqi@0 92 /**
aoqi@0 93 * Start the generation of files. Call generate methods in the individual
aoqi@0 94 * writers, which will in turn genrate the documentation files. Call the
aoqi@0 95 * TreeWriter generation first to ensure the Class Hierarchy is built
aoqi@0 96 * first and then can be used in the later generation.
aoqi@0 97 *
aoqi@0 98 * For new format.
aoqi@0 99 *
aoqi@0 100 * @see com.sun.javadoc.RootDoc
aoqi@0 101 */
aoqi@0 102 protected void generateOtherFiles(RootDoc root, ClassTree classtree)
aoqi@0 103 throws Exception {
aoqi@0 104 super.generateOtherFiles(root, classtree);
aoqi@0 105 if (configuration.linksource) {
aoqi@0 106 SourceToHTMLConverter.convertRoot(configuration,
aoqi@0 107 root, DocPaths.SOURCE_OUTPUT);
aoqi@0 108 }
aoqi@0 109
aoqi@0 110 if (configuration.topFile.isEmpty()) {
aoqi@0 111 configuration.standardmessage.
aoqi@0 112 error("doclet.No_Non_Deprecated_Classes_To_Document");
aoqi@0 113 return;
aoqi@0 114 }
aoqi@0 115 boolean nodeprecated = configuration.nodeprecated;
aoqi@0 116 performCopy(configuration.helpfile);
aoqi@0 117 performCopy(configuration.stylesheetfile);
aoqi@0 118 // do early to reduce memory footprint
aoqi@0 119 if (configuration.classuse) {
aoqi@0 120 ClassUseWriter.generate(configuration, classtree);
aoqi@0 121 }
aoqi@0 122 IndexBuilder indexbuilder = new IndexBuilder(configuration, nodeprecated);
aoqi@0 123
aoqi@0 124 if (configuration.createtree) {
aoqi@0 125 TreeWriter.generate(configuration, classtree);
aoqi@0 126 }
aoqi@0 127 if (configuration.createindex) {
aoqi@0 128 if (configuration.splitindex) {
aoqi@0 129 SplitIndexWriter.generate(configuration, indexbuilder);
aoqi@0 130 } else {
aoqi@0 131 SingleIndexWriter.generate(configuration, indexbuilder);
aoqi@0 132 }
aoqi@0 133 }
aoqi@0 134
aoqi@0 135 if (!(configuration.nodeprecatedlist || nodeprecated)) {
aoqi@0 136 DeprecatedListWriter.generate(configuration);
aoqi@0 137 }
aoqi@0 138
aoqi@0 139 AllClassesFrameWriter.generate(configuration,
aoqi@0 140 new IndexBuilder(configuration, nodeprecated, true));
aoqi@0 141
aoqi@0 142 FrameOutputWriter.generate(configuration);
aoqi@0 143
aoqi@0 144 if (configuration.createoverview) {
aoqi@0 145 PackageIndexWriter.generate(configuration);
aoqi@0 146 }
aoqi@0 147 if (configuration.helpfile.length() == 0 &&
aoqi@0 148 !configuration.nohelp) {
aoqi@0 149 HelpWriter.generate(configuration);
aoqi@0 150 }
aoqi@0 151 // If a stylesheet file is not specified, copy the default stylesheet
aoqi@0 152 // and replace newline with platform-specific newline.
aoqi@0 153 DocFile f;
aoqi@0 154 if (configuration.stylesheetfile.length() == 0) {
aoqi@0 155 f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
aoqi@0 156 f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
aoqi@0 157 }
aoqi@0 158 f = DocFile.createFileForOutput(configuration, DocPaths.JAVASCRIPT);
aoqi@0 159 f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.JAVASCRIPT), true, true);
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 /**
aoqi@0 163 * {@inheritDoc}
aoqi@0 164 */
aoqi@0 165 protected void generateClassFiles(ClassDoc[] arr, ClassTree classtree) {
aoqi@0 166 Arrays.sort(arr);
aoqi@0 167 for(int i = 0; i < arr.length; i++) {
aoqi@0 168 if (!(configuration.isGeneratedDoc(arr[i]) && arr[i].isIncluded())) {
aoqi@0 169 continue;
aoqi@0 170 }
aoqi@0 171 ClassDoc prev = (i == 0)?
aoqi@0 172 null:
aoqi@0 173 arr[i-1];
aoqi@0 174 ClassDoc curr = arr[i];
aoqi@0 175 ClassDoc next = (i+1 == arr.length)?
aoqi@0 176 null:
aoqi@0 177 arr[i+1];
aoqi@0 178 try {
aoqi@0 179 if (curr.isAnnotationType()) {
aoqi@0 180 AbstractBuilder annotationTypeBuilder =
aoqi@0 181 configuration.getBuilderFactory()
aoqi@0 182 .getAnnotationTypeBuilder((AnnotationTypeDoc) curr,
aoqi@0 183 prev, next);
aoqi@0 184 annotationTypeBuilder.build();
aoqi@0 185 } else {
aoqi@0 186 AbstractBuilder classBuilder =
aoqi@0 187 configuration.getBuilderFactory()
aoqi@0 188 .getClassBuilder(curr, prev, next, classtree);
aoqi@0 189 classBuilder.build();
aoqi@0 190 }
aoqi@0 191 } catch (IOException e) {
aoqi@0 192 throw new DocletAbortException(e);
aefimov@3315 193 } catch (FatalError fe) {
aefimov@3315 194 throw fe;
aoqi@0 195 } catch (DocletAbortException de) {
aoqi@0 196 throw de;
aoqi@0 197 } catch (Exception e) {
aoqi@0 198 e.printStackTrace();
aoqi@0 199 throw new DocletAbortException(e);
aoqi@0 200 }
aoqi@0 201 }
aoqi@0 202 }
aoqi@0 203
aoqi@0 204 /**
aoqi@0 205 * {@inheritDoc}
aoqi@0 206 */
aoqi@0 207 protected void generateProfileFiles() throws Exception {
aoqi@0 208 if (configuration.showProfiles && configuration.profilePackages.size() > 0) {
aoqi@0 209 ProfileIndexFrameWriter.generate(configuration);
aoqi@0 210 Profile prevProfile = null, nextProfile;
aoqi@0 211 String profileName;
aoqi@0 212 for (int i = 1; i < configuration.profiles.getProfileCount(); i++) {
aoqi@0 213 profileName = Profile.lookup(i).name;
aoqi@0 214 // Generate profile package pages only if there are any packages
aoqi@0 215 // in a profile to be documented. The profilePackages map will not
aoqi@0 216 // contain an entry for the profile if there are no packages to be documented.
aoqi@0 217 if (!configuration.shouldDocumentProfile(profileName))
aoqi@0 218 continue;
aoqi@0 219 ProfilePackageIndexFrameWriter.generate(configuration, profileName);
aoqi@0 220 PackageDoc[] packages = configuration.profilePackages.get(
aoqi@0 221 profileName);
aoqi@0 222 PackageDoc prev = null, next;
aoqi@0 223 for (int j = 0; j < packages.length; j++) {
aoqi@0 224 // if -nodeprecated option is set and the package is marked as
aoqi@0 225 // deprecated, do not generate the profilename-package-summary.html
aoqi@0 226 // and profilename-package-frame.html pages for that package.
aoqi@0 227 if (!(configuration.nodeprecated && Util.isDeprecated(packages[j]))) {
aoqi@0 228 ProfilePackageFrameWriter.generate(configuration, packages[j], i);
aoqi@0 229 next = (j + 1 < packages.length
aoqi@0 230 && packages[j + 1].name().length() > 0) ? packages[j + 1] : null;
aoqi@0 231 AbstractBuilder profilePackageSummaryBuilder =
aoqi@0 232 configuration.getBuilderFactory().getProfilePackageSummaryBuilder(
aoqi@0 233 packages[j], prev, next, Profile.lookup(i));
aoqi@0 234 profilePackageSummaryBuilder.build();
aoqi@0 235 prev = packages[j];
aoqi@0 236 }
aoqi@0 237 }
aoqi@0 238 nextProfile = (i + 1 < configuration.profiles.getProfileCount()) ?
aoqi@0 239 Profile.lookup(i + 1) : null;
aoqi@0 240 AbstractBuilder profileSummaryBuilder =
aoqi@0 241 configuration.getBuilderFactory().getProfileSummaryBuilder(
aoqi@0 242 Profile.lookup(i), prevProfile, nextProfile);
aoqi@0 243 profileSummaryBuilder.build();
aoqi@0 244 prevProfile = Profile.lookup(i);
aoqi@0 245 }
aoqi@0 246 }
aoqi@0 247 }
aoqi@0 248
aoqi@0 249 /**
aoqi@0 250 * {@inheritDoc}
aoqi@0 251 */
aoqi@0 252 protected void generatePackageFiles(ClassTree classtree) throws Exception {
aoqi@0 253 PackageDoc[] packages = configuration.packages;
aoqi@0 254 if (packages.length > 1) {
aoqi@0 255 PackageIndexFrameWriter.generate(configuration);
aoqi@0 256 }
aoqi@0 257 PackageDoc prev = null, next;
aoqi@0 258 for (int i = 0; i < packages.length; i++) {
aoqi@0 259 // if -nodeprecated option is set and the package is marked as
aoqi@0 260 // deprecated, do not generate the package-summary.html, package-frame.html
aoqi@0 261 // and package-tree.html pages for that package.
aoqi@0 262 if (!(configuration.nodeprecated && Util.isDeprecated(packages[i]))) {
aoqi@0 263 PackageFrameWriter.generate(configuration, packages[i]);
aoqi@0 264 next = (i + 1 < packages.length &&
aoqi@0 265 packages[i + 1].name().length() > 0) ? packages[i + 1] : null;
aoqi@0 266 //If the next package is unnamed package, skip 2 ahead if possible
aoqi@0 267 next = (i + 2 < packages.length && next == null) ? packages[i + 2] : next;
aoqi@0 268 AbstractBuilder packageSummaryBuilder =
aoqi@0 269 configuration.getBuilderFactory().getPackageSummaryBuilder(
aoqi@0 270 packages[i], prev, next);
aoqi@0 271 packageSummaryBuilder.build();
aoqi@0 272 if (configuration.createtree) {
aoqi@0 273 PackageTreeWriter.generate(configuration,
aoqi@0 274 packages[i], prev, next,
aoqi@0 275 configuration.nodeprecated);
aoqi@0 276 }
aoqi@0 277 prev = packages[i];
aoqi@0 278 }
aoqi@0 279 }
aoqi@0 280 }
aoqi@0 281
aoqi@0 282 public static final ConfigurationImpl sharedInstanceForOptions =
aoqi@0 283 new ConfigurationImpl();
aoqi@0 284
aoqi@0 285 /**
aoqi@0 286 * Check for doclet added options here.
aoqi@0 287 *
aoqi@0 288 * @return number of arguments to option. Zero return means
aoqi@0 289 * option not known. Negative value means error occurred.
aoqi@0 290 */
aoqi@0 291 public static int optionLength(String option) {
aoqi@0 292 // Construct temporary configuration for check
aoqi@0 293 return sharedInstanceForOptions.optionLength(option);
aoqi@0 294 }
aoqi@0 295
aoqi@0 296 /**
aoqi@0 297 * Check that options have the correct arguments here.
aoqi@0 298 * <P>
aoqi@0 299 * This method is not required and will default gracefully
aoqi@0 300 * (to true) if absent.
aoqi@0 301 * <P>
aoqi@0 302 * Printing option related error messages (using the provided
aoqi@0 303 * DocErrorReporter) is the responsibility of this method.
aoqi@0 304 *
aoqi@0 305 * @return true if the options are valid.
aoqi@0 306 */
aoqi@0 307 public static boolean validOptions(String options[][],
aoqi@0 308 DocErrorReporter reporter) {
aoqi@0 309 docletToStart = new HtmlDoclet();
aoqi@0 310 return docletToStart.configuration.validOptions(options, reporter);
aoqi@0 311 }
aoqi@0 312
aoqi@0 313 private void performCopy(String filename) {
aoqi@0 314 if (filename.isEmpty())
aoqi@0 315 return;
aoqi@0 316
aoqi@0 317 try {
aoqi@0 318 DocFile fromfile = DocFile.createFileForInput(configuration, filename);
aoqi@0 319 DocPath path = DocPath.create(fromfile.getName());
aoqi@0 320 DocFile toFile = DocFile.createFileForOutput(configuration, path);
aoqi@0 321 if (toFile.isSameFile(fromfile))
aoqi@0 322 return;
aoqi@0 323
aoqi@0 324 configuration.message.notice((SourcePosition) null,
aoqi@0 325 "doclet.Copying_File_0_To_File_1",
aoqi@0 326 fromfile.toString(), path.getPath());
aoqi@0 327 toFile.copyFile(fromfile);
aoqi@0 328 } catch (IOException exc) {
aoqi@0 329 configuration.message.error((SourcePosition) null,
aoqi@0 330 "doclet.perform_copy_exception_encountered",
aoqi@0 331 exc.toString());
aoqi@0 332 throw new DocletAbortException(exc);
aoqi@0 333 }
aoqi@0 334 }
aoqi@0 335 }

mercurial