1 /* 2 * Copyright (c) 1997, 2018, 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 26 package jdk.javadoc.internal.doclets.formats.html; 27 28 import jdk.javadoc.internal.doclets.formats.html.markup.Table; 29 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; 30 31 import java.util.*; 32 33 import javax.lang.model.element.ModuleElement; 34 import javax.lang.model.element.PackageElement; 35 import javax.lang.model.element.TypeElement; 36 37 import com.sun.source.doctree.DocTree; 38 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; 40 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 41 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 42 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 43 import jdk.javadoc.internal.doclets.formats.html.markup.Links; 44 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 45 import jdk.javadoc.internal.doclets.toolkit.Content; 46 import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter; 47 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; 48 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; 49 import jdk.javadoc.internal.doclets.toolkit.util.DocPath; 50 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 51 52 /** 53 * Class to generate file for each package contents in the right-hand 54 * frame. This will list all the Class Kinds in the package. A click on any 55 * class-kind will update the frame with the clicked class-kind page. 56 * 57 * <p><b>This is NOT part of any supported API. 58 * If you write code that depends on this, you do so at your own risk. 59 * This code and its internal interfaces are subject to change or 60 * deletion without notice.</b> 61 * 62 * @author Atul M Dambalkar 63 * @author Bhavesh Patel (Modified) 64 */ 65 public class PackageWriterImpl extends HtmlDocletWriter 66 implements PackageSummaryWriter { 67 68 /** 69 * The prev package name in the alpha-order list. 70 */ 71 protected PackageElement prev; 72 73 /** 74 * The next package name in the alpha-order list. 75 */ 76 protected PackageElement next; 77 78 /** 79 * The package being documented. 80 */ 81 protected PackageElement packageElement; 82 83 /** 84 * The HTML tree for main tag. 85 */ 86 protected HtmlTree mainTree = HtmlTree.MAIN(); 87 88 /** 89 * The HTML tree for section tag. 90 */ 91 protected HtmlTree sectionTree = HtmlTree.SECTION(); 92 93 /** 94 * Constructor to construct PackageWriter object and to generate 95 * "package-summary.html" file in the respective package directory. 96 * For example for package "java.lang" this will generate file 97 * "package-summary.html" file in the "java/lang" directory. It will also 98 * create "java/lang" directory in the current or the destination directory 99 * if it doesn't exist. 100 * 101 * @param configuration the configuration of the doclet. 102 * @param packageElement PackageElement under consideration. 103 * @param prev Previous package in the sorted array. 104 * @param next Next package in the sorted array. 105 */ 106 public PackageWriterImpl(HtmlConfiguration configuration, 107 PackageElement packageElement, PackageElement prev, PackageElement next) { 108 super(configuration, 109 configuration.docPaths.forPackage(packageElement) 110 .resolve(DocPaths.PACKAGE_SUMMARY)); 111 this.prev = prev; 112 this.next = next; 113 this.packageElement = packageElement; 114 } 115 116 /** 117 * {@inheritDoc} 118 */ 119 @Override 120 public Content getPackageHeader(String heading) { 121 HtmlTree bodyTree = getBody(true, getWindowTitle(utils.getPackageName(packageElement))); 122 HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER)) 123 ? HtmlTree.HEADER() 124 : bodyTree; 125 addTop(htmlTree); 126 addNavLinks(true, htmlTree); 127 if (configuration.allowTag(HtmlTag.HEADER)) { 128 bodyTree.addContent(htmlTree); 129 } 130 HtmlTree div = new HtmlTree(HtmlTag.DIV); 131 div.setStyle(HtmlStyle.header); 132 if (configuration.showModules) { 133 ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement); 134 Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel); 135 Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel); 136 moduleNameDiv.addContent(Contents.SPACE); 137 moduleNameDiv.addContent(getModuleLink(mdle, 138 new StringContent(mdle.getQualifiedName().toString()))); 139 div.addContent(moduleNameDiv); 140 } 141 Content annotationContent = new HtmlTree(HtmlTag.P); 142 addAnnotationInfo(packageElement, annotationContent); 143 div.addContent(annotationContent); 144 Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true, 145 HtmlStyle.title, contents.packageLabel); 146 tHeading.addContent(Contents.SPACE); 147 Content packageHead = new StringContent(heading); 148 tHeading.addContent(packageHead); 149 div.addContent(tHeading); 150 if (configuration.allowTag(HtmlTag.MAIN)) { 151 mainTree.addContent(div); 152 } else { 153 bodyTree.addContent(div); 154 } 155 return bodyTree; 156 } 157 158 /** 159 * {@inheritDoc} 160 */ 161 @Override 162 public Content getContentHeader() { 163 HtmlTree div = new HtmlTree(HtmlTag.DIV); 164 div.setStyle(HtmlStyle.contentContainer); 165 return div; 166 } 167 168 /** 169 * Add the package deprecation information to the documentation tree. 170 * 171 * @param div the content tree to which the deprecation information will be added 172 */ 173 public void addDeprecationInfo(Content div) { 174 List<? extends DocTree> deprs = utils.getBlockTags(packageElement, DocTree.Kind.DEPRECATED); 175 if (utils.isDeprecated(packageElement)) { 176 CommentHelper ch = utils.getCommentHelper(packageElement); 177 HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV); 178 deprDiv.setStyle(HtmlStyle.deprecationBlock); 179 Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement)); 180 deprDiv.addContent(deprPhrase); 181 if (!deprs.isEmpty()) { 182 List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0)); 183 if (!commentTags.isEmpty()) { 184 addInlineDeprecatedComment(packageElement, deprs.get(0), deprDiv); 185 } 186 } 187 div.addContent(deprDiv); 188 } 189 } 190 191 /** 192 * {@inheritDoc} 193 */ 194 @Override 195 public Content getSummaryHeader() { 196 HtmlTree ul = new HtmlTree(HtmlTag.UL); 197 ul.setStyle(HtmlStyle.blockList); 198 return ul; 199 } 200 201 /** 202 * {@inheritDoc} 203 */ 204 @Override 205 public void addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree) { 206 String label = resources.getText("doclet.Interface_Summary"); 207 String tableSummary = resources.getText("doclet.Member_Table_Summary", 208 resources.getText("doclet.Interface_Summary"), 209 resources.getText("doclet.interfaces")); 210 TableHeader tableHeader= new TableHeader(contents.interfaceLabel, contents.descriptionLabel); 211 212 addClassesSummary(interfaces, label, tableSummary, tableHeader, summaryContentTree); 213 } 214 215 /** 216 * {@inheritDoc} 217 */ 218 @Override 219 public void addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree) { 220 String label = resources.getText("doclet.Class_Summary"); 221 String tableSummary = resources.getText("doclet.Member_Table_Summary", 222 resources.getText("doclet.Class_Summary"), 223 resources.getText("doclet.classes")); 224 TableHeader tableHeader= new TableHeader(contents.classLabel, contents.descriptionLabel); 225 226 addClassesSummary(classes, label, tableSummary, tableHeader, summaryContentTree); 227 } 228 229 /** 230 * {@inheritDoc} 231 */ 232 @Override 233 public void addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree) { 234 String label = resources.getText("doclet.Enum_Summary"); 235 String tableSummary = resources.getText("doclet.Member_Table_Summary", 236 resources.getText("doclet.Enum_Summary"), 237 resources.getText("doclet.enums")); 238 TableHeader tableHeader= new TableHeader(contents.enum_, contents.descriptionLabel); 239 240 addClassesSummary(enums, label, tableSummary, tableHeader, summaryContentTree); 241 } 242 243 /** 244 * {@inheritDoc} 245 */ 246 @Override 247 public void addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree) { 248 String label = resources.getText("doclet.Exception_Summary"); 249 String tableSummary = resources.getText("doclet.Member_Table_Summary", 250 resources.getText("doclet.Exception_Summary"), 251 resources.getText("doclet.exceptions")); 252 TableHeader tableHeader= new TableHeader(contents.exception, contents.descriptionLabel); 253 254 addClassesSummary(exceptions, label, tableSummary, tableHeader, summaryContentTree); 255 } 256 257 /** 258 * {@inheritDoc} 259 */ 260 @Override 261 public void addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree) { 262 String label = resources.getText("doclet.Error_Summary"); 263 String tableSummary = resources.getText("doclet.Member_Table_Summary", 264 resources.getText("doclet.Error_Summary"), 265 resources.getText("doclet.errors")); 266 TableHeader tableHeader= new TableHeader(contents.error, contents.descriptionLabel); 267 268 addClassesSummary(errors, label, tableSummary, tableHeader, summaryContentTree); 269 } 270 271 /** 272 * {@inheritDoc} 273 */ 274 @Override 275 public void addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree) { 276 String label = resources.getText("doclet.Annotation_Types_Summary"); 277 String tableSummary = resources.getText("doclet.Member_Table_Summary", 278 resources.getText("doclet.Annotation_Types_Summary"), 279 resources.getText("doclet.annotationtypes")); 280 TableHeader tableHeader= new TableHeader(contents.annotationType, contents.descriptionLabel); 281 282 addClassesSummary(annoTypes, label, tableSummary, tableHeader, summaryContentTree); 283 } 284 285 public void addClassesSummary(SortedSet<TypeElement> classes, String label, 286 String tableSummary, TableHeader tableHeader, Content summaryContentTree) { 287 if(!classes.isEmpty()) { 288 Table table = new Table(configuration.htmlVersion, HtmlStyle.typeSummary) 289 .setSummary(tableSummary) 290 .setCaption(getTableCaption(new StringContent(label))) 291 .setHeader(tableHeader) 292 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast); 293 294 for (TypeElement klass : classes) { 295 if (!utils.isCoreClass(klass) || !configuration.isGeneratedDoc(klass)) { 296 continue; 297 } 298 Content classLink = getLink(new LinkInfoImpl( 299 configuration, LinkInfoImpl.Kind.PACKAGE, klass)); 300 ContentBuilder description = new ContentBuilder(); 301 if (utils.isDeprecated(klass)) { 302 description.addContent(getDeprecatedPhrase(klass)); 303 List<? extends DocTree> tags = utils.getDeprecatedTrees(klass); 304 if (!tags.isEmpty()) { 305 addSummaryDeprecatedComment(klass, tags.get(0), description); 306 } 307 } else { 308 addSummaryComment(klass, description); 309 } 310 table.addRow(classLink, description); 311 } 312 Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent()); 313 summaryContentTree.addContent(li); 314 } 315 } 316 317 /** 318 * {@inheritDoc} 319 */ 320 @Override 321 public void addPackageDescription(Content packageContentTree) { 322 if (!utils.getBody(packageElement).isEmpty()) { 323 Content tree = configuration.allowTag(HtmlTag.SECTION) ? sectionTree : packageContentTree; 324 tree.addContent(links.createAnchor(SectionName.PACKAGE_DESCRIPTION)); 325 addDeprecationInfo(tree); 326 addInlineComment(packageElement, tree); 327 } 328 } 329 330 /** 331 * {@inheritDoc} 332 */ 333 @Override 334 public void addPackageTags(Content packageContentTree) { 335 Content htmlTree = (configuration.allowTag(HtmlTag.SECTION)) 336 ? sectionTree 337 : packageContentTree; 338 addTagsInfo(packageElement, htmlTree); 339 if (configuration.allowTag(HtmlTag.SECTION)) { 340 packageContentTree.addContent(sectionTree); 341 } 342 } 343 344 /** 345 * {@inheritDoc} 346 */ 347 @Override 348 public void addPackageContent(Content contentTree, Content packageContentTree) { 349 if (configuration.allowTag(HtmlTag.MAIN)) { 350 mainTree.addContent(packageContentTree); 351 contentTree.addContent(mainTree); 352 } else { 353 contentTree.addContent(packageContentTree); 354 } 355 } 356 357 /** 358 * {@inheritDoc} 359 */ 360 @Override 361 public void addPackageFooter(Content contentTree) { 362 Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER)) 363 ? HtmlTree.FOOTER() 364 : contentTree; 365 addNavLinks(false, htmlTree); 366 addBottom(htmlTree); 367 if (configuration.allowTag(HtmlTag.FOOTER)) { 368 contentTree.addContent(htmlTree); 369 } 370 } 371 372 /** 373 * {@inheritDoc} 374 */ 375 @Override 376 public void printDocument(Content contentTree) throws DocFileIOException { 377 printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement), 378 true, contentTree); 379 } 380 381 /** 382 * Get "Use" link for this pacakge in the navigation bar. 383 * 384 * @return a content tree for the class use link 385 */ 386 @Override 387 protected Content getNavLinkClassUse() { 388 Content useLink = links.createLink(DocPaths.PACKAGE_USE, 389 contents.useLabel, "", ""); 390 Content li = HtmlTree.LI(useLink); 391 return li; 392 } 393 394 /** 395 * Get "PREV PACKAGE" link in the navigation bar. 396 * 397 * @return a content tree for the previous link 398 */ 399 @Override 400 public Content getNavLinkPrevious() { 401 Content li; 402 if (prev == null) { 403 li = HtmlTree.LI(contents.prevPackageLabel); 404 } else { 405 DocPath p = docPaths.relativePath(packageElement, prev); 406 li = HtmlTree.LI(links.createLink(p.resolve(DocPaths.PACKAGE_SUMMARY), 407 contents.prevPackageLabel, "", "")); 408 } 409 return li; 410 } 411 412 /** 413 * Get "NEXT PACKAGE" link in the navigation bar. 414 * 415 * @return a content tree for the next link 416 */ 417 @Override 418 public Content getNavLinkNext() { 419 Content li; 420 if (next == null) { 421 li = HtmlTree.LI(contents.nextPackageLabel); 422 } else { 423 DocPath p = docPaths.relativePath(packageElement, next); 424 li = HtmlTree.LI(links.createLink(p.resolve(DocPaths.PACKAGE_SUMMARY), 425 contents.nextPackageLabel, "", "")); 426 } 427 return li; 428 } 429 430 /** 431 * Get "Tree" link in the navigation bar. This will be link to the package 432 * tree file. 433 * 434 * @return a content tree for the tree link 435 */ 436 @Override 437 protected Content getNavLinkTree() { 438 Content useLink = links.createLink(DocPaths.PACKAGE_TREE, 439 contents.treeLabel, "", ""); 440 Content li = HtmlTree.LI(useLink); 441 return li; 442 } 443 444 /** 445 * Get the module link. 446 * 447 * @return a content tree for the module link 448 */ 449 @Override 450 protected Content getNavLinkModule() { 451 Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), 452 contents.moduleLabel); 453 Content li = HtmlTree.LI(linkContent); 454 return li; 455 } 456 457 /** 458 * Highlight "Package" in the navigation bar, as this is the package page. 459 * 460 * @return a content tree for the package link 461 */ 462 @Override 463 protected Content getNavLinkPackage() { 464 Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.packageLabel); 465 return li; 466 } 467 }