1 /*
   2  * Copyright (c) 1997, 2019, 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.List;
  29 import java.util.SortedSet;
  30 
  31 import javax.lang.model.element.ModuleElement;
  32 import javax.lang.model.element.PackageElement;
  33 import javax.lang.model.element.TypeElement;
  34 
  35 import com.sun.source.doctree.DocTree;
  36 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
  37 import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
  38 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
  39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
  40 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
  41 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
  42 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
  43 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
  44 import jdk.javadoc.internal.doclets.formats.html.markup.Table;
  45 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader;
  46 import jdk.javadoc.internal.doclets.toolkit.Content;
  47 import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
  48 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
  49 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
  50 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
  51 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
  52 
  53 /**
  54  * Class to generate file for each package contents in the right-hand
  55  * frame. This will list all the Class Kinds in the package. A click on any
  56  * class-kind will update the frame with the clicked class-kind page.
  57  *
  58  *  <p><b>This is NOT part of any supported API.
  59  *  If you write code that depends on this, you do so at your own risk.
  60  *  This code and its internal interfaces are subject to change or
  61  *  deletion without notice.</b>
  62  *
  63  * @author Atul M Dambalkar
  64  * @author Bhavesh Patel (Modified)
  65  */
  66 public class PackageWriterImpl extends HtmlDocletWriter
  67     implements PackageSummaryWriter {
  68 
  69     /**
  70      * The package being documented.
  71      */
  72     protected PackageElement packageElement;
  73 
  74     /**
  75      * The HTML tree for main tag.
  76      */
  77     protected HtmlTree mainTree = HtmlTree.MAIN();
  78 
  79     /**
  80      * The HTML tree for section tag.
  81      */
  82     protected HtmlTree sectionTree = HtmlTree.SECTION(HtmlStyle.packageDescription, new ContentBuilder());
  83 
  84     private final Navigation navBar;
  85 
  86     /**
  87      * Constructor to construct PackageWriter object and to generate
  88      * "package-summary.html" file in the respective package directory.
  89      * For example for package "java.lang" this will generate file
  90      * "package-summary.html" file in the "java/lang" directory. It will also
  91      * create "java/lang" directory in the current or the destination directory
  92      * if it doesn't exist.
  93      *
  94      * @param configuration the configuration of the doclet.
  95      * @param packageElement    PackageElement under consideration.
  96      */
  97     public PackageWriterImpl(HtmlConfiguration configuration, PackageElement packageElement) {
  98         super(configuration,
  99                 configuration.docPaths.forPackage(packageElement)
 100                 .resolve(DocPaths.PACKAGE_SUMMARY));
 101         this.packageElement = packageElement;
 102         this.navBar = new Navigation(packageElement, configuration, fixedNavDiv, PageMode.PACKAGE, path);
 103     }
 104 
 105     /**
 106      * {@inheritDoc}
 107      */
 108     @Override
 109     public Content getPackageHeader(String heading) {
 110         HtmlTree bodyTree = getBody(getWindowTitle(utils.getPackageName(packageElement)));
 111         HtmlTree htmlTree = HtmlTree.HEADER();
 112         addTop(htmlTree);
 113         Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
 114                 contents.moduleLabel);
 115         navBar.setNavLinkModule(linkContent);
 116         navBar.setUserHeader(getUserHeaderFooter(true));
 117         htmlTree.add(navBar.getContent(true));
 118         bodyTree.add(htmlTree);
 119         HtmlTree div = new HtmlTree(HtmlTag.DIV);
 120         div.setStyle(HtmlStyle.header);
 121         if (configuration.showModules) {
 122             ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement);
 123             Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel);
 124             Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel);
 125             moduleNameDiv.add(Entity.NO_BREAK_SPACE);
 126             moduleNameDiv.add(getModuleLink(mdle,
 127                     new StringContent(mdle.getQualifiedName().toString())));
 128             div.add(moduleNameDiv);
 129         }
 130         Content annotationContent = new HtmlTree(HtmlTag.P);
 131         addAnnotationInfo(packageElement, annotationContent);
 132         div.add(annotationContent);
 133         Content tHeading = HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, true,
 134                 HtmlStyle.title, contents.packageLabel);
 135         tHeading.add(Entity.NO_BREAK_SPACE);
 136         Content packageHead = new StringContent(heading);
 137         tHeading.add(packageHead);
 138         div.add(tHeading);
 139         mainTree.add(div);
 140         return bodyTree;
 141     }
 142 
 143     /**
 144      * {@inheritDoc}
 145      */
 146     @Override
 147     public Content getContentHeader() {
 148         HtmlTree div = new HtmlTree(HtmlTag.DIV);
 149         div.setStyle(HtmlStyle.contentContainer);
 150         return div;
 151     }
 152 
 153     /**
 154      * Add the package deprecation information to the documentation tree.
 155      *
 156      * @param div the content tree to which the deprecation information will be added
 157      */
 158     public void addDeprecationInfo(Content div) {
 159         List<? extends DocTree> deprs = utils.getBlockTags(packageElement, DocTree.Kind.DEPRECATED);
 160         if (utils.isDeprecated(packageElement)) {
 161             CommentHelper ch = utils.getCommentHelper(packageElement);
 162             HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
 163             deprDiv.setStyle(HtmlStyle.deprecationBlock);
 164             Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement));
 165             deprDiv.add(deprPhrase);
 166             if (!deprs.isEmpty()) {
 167                 List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
 168                 if (!commentTags.isEmpty()) {
 169                     addInlineDeprecatedComment(packageElement, deprs.get(0), deprDiv);
 170                 }
 171             }
 172             div.add(deprDiv);
 173         }
 174     }
 175 
 176     /**
 177      * {@inheritDoc}
 178      */
 179     @Override
 180     public Content getSummaryHeader() {
 181         HtmlTree ul = new HtmlTree(HtmlTag.UL);
 182         ul.setStyle(HtmlStyle.blockList);
 183         return ul;
 184     }
 185 
 186     /**
 187      * {@inheritDoc}
 188      */
 189     @Override
 190     public void addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree) {
 191         TableHeader tableHeader= new TableHeader(contents.interfaceLabel, contents.descriptionLabel);
 192         addClassesSummary(interfaces, resources.interfaceSummary, tableHeader, summaryContentTree);
 193     }
 194 
 195     /**
 196      * {@inheritDoc}
 197      */
 198     @Override
 199     public void addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree) {
 200         TableHeader tableHeader= new TableHeader(contents.classLabel, contents.descriptionLabel);
 201         addClassesSummary(classes, resources.classSummary, tableHeader, summaryContentTree);
 202     }
 203 
 204     /**
 205      * {@inheritDoc}
 206      */
 207     @Override
 208     public void addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree) {
 209         TableHeader tableHeader= new TableHeader(contents.enum_, contents.descriptionLabel);
 210         addClassesSummary(enums, resources.enumSummary, tableHeader, summaryContentTree);
 211     }
 212 
 213     /**
 214      * {@inheritDoc}
 215      */
 216     @Override
 217     public void addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree) {
 218         TableHeader tableHeader= new TableHeader(contents.exception, contents.descriptionLabel);
 219         addClassesSummary(exceptions, resources.exceptionSummary, tableHeader, summaryContentTree);
 220     }
 221 
 222     /**
 223      * {@inheritDoc}
 224      */
 225     @Override
 226     public void addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree) {
 227         TableHeader tableHeader= new TableHeader(contents.error, contents.descriptionLabel);
 228         addClassesSummary(errors, resources.errorSummary, tableHeader, summaryContentTree);
 229     }
 230 
 231     /**
 232      * {@inheritDoc}
 233      */
 234     @Override
 235     public void addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree) {
 236         TableHeader tableHeader= new TableHeader(contents.annotationType, contents.descriptionLabel);
 237         addClassesSummary(annoTypes, resources.annotationTypeSummary, tableHeader, summaryContentTree);
 238     }
 239 
 240     public void addClassesSummary(SortedSet<TypeElement> classes, String label,
 241             TableHeader tableHeader, Content summaryContentTree) {
 242         if(!classes.isEmpty()) {
 243             Table table = new Table(HtmlStyle.typeSummary)
 244                     .setCaption(getTableCaption(new StringContent(label)))
 245                     .setHeader(tableHeader)
 246                     .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
 247 
 248             for (TypeElement klass : classes) {
 249                 if (!utils.isCoreClass(klass) || !configuration.isGeneratedDoc(klass)) {
 250                     continue;
 251                 }
 252                 Content classLink = getLink(new LinkInfoImpl(
 253                         configuration, LinkInfoImpl.Kind.PACKAGE, klass));
 254                 ContentBuilder description = new ContentBuilder();
 255                 if (utils.isDeprecated(klass)) {
 256                     description.add(getDeprecatedPhrase(klass));
 257                     List<? extends DocTree> tags = utils.getDeprecatedTrees(klass);
 258                     if (!tags.isEmpty()) {
 259                         addSummaryDeprecatedComment(klass, tags.get(0), description);
 260                     }
 261                 } else {
 262                     addSummaryComment(klass, description);
 263                 }
 264                 table.addRow(classLink, description);
 265             }
 266             Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent());
 267             summaryContentTree.add(li);
 268         }
 269     }
 270 
 271     /**
 272      * {@inheritDoc}
 273      */
 274     @Override
 275     public void addPackageDescription(Content packageContentTree) {
 276         if (!utils.getBody(packageElement).isEmpty()) {
 277             Content tree = sectionTree;
 278             tree.add(links.createAnchor(SectionName.PACKAGE_DESCRIPTION));
 279             addDeprecationInfo(tree);
 280             addInlineComment(packageElement, tree);
 281         }
 282     }
 283 
 284     /**
 285      * {@inheritDoc}
 286      */
 287     @Override
 288     public void addPackageTags(Content packageContentTree) {
 289         Content htmlTree = sectionTree;
 290         addTagsInfo(packageElement, htmlTree);
 291         packageContentTree.add(sectionTree);
 292     }
 293 
 294     /**
 295      * {@inheritDoc}
 296      */
 297     @Override
 298     public void addPackageContent(Content contentTree, Content packageContentTree) {
 299         mainTree.add(packageContentTree);
 300         contentTree.add(mainTree);
 301     }
 302 
 303     /**
 304      * {@inheritDoc}
 305      */
 306     @Override
 307     public void addPackageFooter(Content contentTree) {
 308         Content htmlTree = HtmlTree.FOOTER();
 309         navBar.setUserFooter(getUserHeaderFooter(false));
 310         htmlTree.add(navBar.getContent(false));
 311         addBottom(htmlTree);
 312         contentTree.add(htmlTree);
 313     }
 314 
 315     /**
 316      * {@inheritDoc}
 317      */
 318     @Override
 319     public void printDocument(Content contentTree) throws DocFileIOException {
 320         String description = getDescription("declaration", packageElement);
 321         List<DocPath> localStylesheets = getLocalStylesheets(packageElement);
 322         printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement),
 323                 description, localStylesheets, contentTree);
 324     }
 325 
 326     /**
 327      * {@inheritDoc}
 328      */
 329     @Override
 330     public Content getPackageSummary(Content summaryContentTree) {
 331         return HtmlTree.SECTION(HtmlStyle.summary, summaryContentTree);
 332     }
 333 }