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