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 }