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