1 /* 2 * Copyright (c) 1997, 2020, 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.BodyContents; 37 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; 38 import jdk.javadoc.internal.doclets.formats.html.markup.Entity; 39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 40 import jdk.javadoc.internal.doclets.formats.html.markup.TagName; 41 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 42 import jdk.javadoc.internal.doclets.formats.html.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 public class PackageWriterImpl extends HtmlDocletWriter 64 implements PackageSummaryWriter { 65 66 /** 67 * The package being documented. 68 */ 69 protected PackageElement packageElement; 70 71 /** 72 * The HTML tree for section tag. 73 */ 74 protected HtmlTree sectionTree = HtmlTree.SECTION(HtmlStyle.packageDescription, new ContentBuilder()); 75 76 private final Navigation navBar; 77 78 private final BodyContents bodyContents = new BodyContents(); 79 80 /** 81 * Constructor to construct PackageWriter object and to generate 82 * "package-summary.html" file in the respective package directory. 83 * For example for package "java.lang" this will generate file 84 * "package-summary.html" file in the "java/lang" directory. It will also 85 * create "java/lang" directory in the current or the destination directory 86 * if it doesn't exist. 87 * 88 * @param configuration the configuration of the doclet. 89 * @param packageElement PackageElement under consideration. 90 */ PackageWriterImpl(HtmlConfiguration configuration, PackageElement packageElement)91 public PackageWriterImpl(HtmlConfiguration configuration, PackageElement packageElement) { 92 super(configuration, 93 configuration.docPaths.forPackage(packageElement) 94 .resolve(DocPaths.PACKAGE_SUMMARY)); 95 this.packageElement = packageElement; 96 this.navBar = new Navigation(packageElement, configuration, PageMode.PACKAGE, path); 97 } 98 99 @Override getPackageHeader(String heading)100 public Content getPackageHeader(String heading) { 101 HtmlTree bodyTree = getBody(getWindowTitle(utils.getPackageName(packageElement))); 102 Content headerContent = new ContentBuilder(); 103 addTop(headerContent); 104 Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), 105 contents.moduleLabel); 106 navBar.setNavLinkModule(linkContent); 107 navBar.setUserHeader(getUserHeaderFooter(true)); 108 headerContent.add(navBar.getContent(Navigation.Position.TOP)); 109 HtmlTree div = new HtmlTree(TagName.DIV); 110 div.setStyle(HtmlStyle.header); 111 if (configuration.showModules) { 112 ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(packageElement); 113 Content classModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInPackage, contents.moduleLabel); 114 Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, classModuleLabel); 115 moduleNameDiv.add(Entity.NO_BREAK_SPACE); 116 moduleNameDiv.add(getModuleLink(mdle, 117 new StringContent(mdle.getQualifiedName().toString()))); 118 div.add(moduleNameDiv); 119 } 120 Content annotationContent = new HtmlTree(TagName.P); 121 addAnnotationInfo(packageElement, annotationContent); 122 div.add(annotationContent); 123 Content tHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, 124 HtmlStyle.title, contents.packageLabel); 125 tHeading.add(Entity.NO_BREAK_SPACE); 126 Content packageHead = new StringContent(heading); 127 tHeading.add(packageHead); 128 div.add(tHeading); 129 bodyContents.setHeader(headerContent) 130 .addMainContent(div); 131 return bodyTree; 132 } 133 134 @Override getContentHeader()135 public Content getContentHeader() { 136 return new ContentBuilder(); 137 } 138 139 /** 140 * Add the package deprecation information to the documentation tree. 141 * 142 * @param div the content tree to which the deprecation information will be added 143 */ addDeprecationInfo(Content div)144 public void addDeprecationInfo(Content div) { 145 List<? extends DocTree> deprs = utils.getBlockTags(packageElement, DocTree.Kind.DEPRECATED); 146 if (utils.isDeprecated(packageElement)) { 147 CommentHelper ch = utils.getCommentHelper(packageElement); 148 HtmlTree deprDiv = new HtmlTree(TagName.DIV); 149 deprDiv.setStyle(HtmlStyle.deprecationBlock); 150 Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement)); 151 deprDiv.add(deprPhrase); 152 if (!deprs.isEmpty()) { 153 List<? extends DocTree> commentTags = ch.getDescription(deprs.get(0)); 154 if (!commentTags.isEmpty()) { 155 addInlineDeprecatedComment(packageElement, deprs.get(0), deprDiv); 156 } 157 } 158 div.add(deprDiv); 159 } 160 } 161 162 @Override getSummariesList()163 public Content getSummariesList() { 164 return new HtmlTree(TagName.UL).setStyle(HtmlStyle.summaryList); 165 } 166 167 @Override addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree)168 public void addInterfaceSummary(SortedSet<TypeElement> interfaces, Content summaryContentTree) { 169 TableHeader tableHeader= new TableHeader(contents.interfaceLabel, contents.descriptionLabel); 170 addClassesSummary(interfaces, resources.interfaceSummary, tableHeader, summaryContentTree); 171 } 172 173 @Override addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree)174 public void addClassSummary(SortedSet<TypeElement> classes, Content summaryContentTree) { 175 TableHeader tableHeader= new TableHeader(contents.classLabel, contents.descriptionLabel); 176 addClassesSummary(classes, resources.classSummary, tableHeader, summaryContentTree); 177 } 178 179 @Override addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree)180 public void addEnumSummary(SortedSet<TypeElement> enums, Content summaryContentTree) { 181 TableHeader tableHeader= new TableHeader(contents.enum_, contents.descriptionLabel); 182 addClassesSummary(enums, resources.enumSummary, tableHeader, summaryContentTree); 183 } 184 185 @Override addRecordSummary(SortedSet<TypeElement> records, Content summaryContentTree)186 public void addRecordSummary(SortedSet<TypeElement> records, Content summaryContentTree) { 187 TableHeader tableHeader= new TableHeader(contents.record, contents.descriptionLabel); 188 addClassesSummary(records, resources.recordSummary, tableHeader, summaryContentTree); 189 } 190 191 @Override addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree)192 public void addExceptionSummary(SortedSet<TypeElement> exceptions, Content summaryContentTree) { 193 TableHeader tableHeader= new TableHeader(contents.exception, contents.descriptionLabel); 194 addClassesSummary(exceptions, resources.exceptionSummary, tableHeader, summaryContentTree); 195 } 196 197 @Override addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree)198 public void addErrorSummary(SortedSet<TypeElement> errors, Content summaryContentTree) { 199 TableHeader tableHeader= new TableHeader(contents.error, contents.descriptionLabel); 200 addClassesSummary(errors, resources.errorSummary, tableHeader, summaryContentTree); 201 } 202 203 @Override addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree)204 public void addAnnotationTypeSummary(SortedSet<TypeElement> annoTypes, Content summaryContentTree) { 205 TableHeader tableHeader= new TableHeader(contents.annotationType, contents.descriptionLabel); 206 addClassesSummary(annoTypes, resources.annotationTypeSummary, tableHeader, summaryContentTree); 207 } 208 addClassesSummary(SortedSet<TypeElement> classes, String label, TableHeader tableHeader, Content summaryContentTree)209 public void addClassesSummary(SortedSet<TypeElement> classes, String label, 210 TableHeader tableHeader, Content summaryContentTree) { 211 if(!classes.isEmpty()) { 212 Table table = new Table(HtmlStyle.typeSummary, HtmlStyle.summaryTable) 213 .setCaption(new StringContent(label)) 214 .setHeader(tableHeader) 215 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast); 216 217 for (TypeElement klass : classes) { 218 if (!utils.isCoreClass(klass) || !configuration.isGeneratedDoc(klass)) { 219 continue; 220 } 221 Content classLink = getLink(new LinkInfoImpl( 222 configuration, LinkInfoImpl.Kind.PACKAGE, klass)); 223 ContentBuilder description = new ContentBuilder(); 224 if (utils.isDeprecated(klass)) { 225 description.add(getDeprecatedPhrase(klass)); 226 List<? extends DocTree> tags = utils.getDeprecatedTrees(klass); 227 if (!tags.isEmpty()) { 228 addSummaryDeprecatedComment(klass, tags.get(0), description); 229 } 230 } else { 231 addSummaryComment(klass, description); 232 } 233 table.addRow(classLink, description); 234 } 235 summaryContentTree.add(HtmlTree.LI(table)); 236 } 237 } 238 239 @Override addPackageDescription(Content packageContentTree)240 public void addPackageDescription(Content packageContentTree) { 241 if (!utils.getBody(packageElement).isEmpty()) { 242 HtmlTree tree = sectionTree; 243 tree.setId(SectionName.PACKAGE_DESCRIPTION.getName()); 244 addDeprecationInfo(tree); 245 addInlineComment(packageElement, tree); 246 } 247 } 248 249 @Override addPackageTags(Content packageContentTree)250 public void addPackageTags(Content packageContentTree) { 251 Content htmlTree = sectionTree; 252 addTagsInfo(packageElement, htmlTree); 253 packageContentTree.add(sectionTree); 254 } 255 256 @Override addPackageContent(Content packageContentTree)257 public void addPackageContent(Content packageContentTree) { 258 bodyContents.addMainContent(packageContentTree); 259 } 260 261 @Override addPackageFooter()262 public void addPackageFooter() { 263 Content htmlTree = HtmlTree.FOOTER(); 264 navBar.setUserFooter(getUserHeaderFooter(false)); 265 htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); 266 addBottom(htmlTree); 267 bodyContents.setFooter(htmlTree); 268 } 269 270 @Override printDocument(Content contentTree)271 public void printDocument(Content contentTree) throws DocFileIOException { 272 String description = getDescription("declaration", packageElement); 273 List<DocPath> localStylesheets = getLocalStylesheets(packageElement); 274 contentTree.add(bodyContents); 275 printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement), 276 description, localStylesheets, contentTree); 277 } 278 279 @Override getPackageSummary(Content summaryContentTree)280 public Content getPackageSummary(Content summaryContentTree) { 281 return HtmlTree.SECTION(HtmlStyle.summary, summaryContentTree); 282 } 283 } 284