1 /* 2 * Copyright (c) 2003, 2018, 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 30 import javax.lang.model.element.ModuleElement; 31 import javax.lang.model.element.PackageElement; 32 import javax.lang.model.element.TypeElement; 33 import javax.lang.model.type.TypeMirror; 34 35 import com.sun.source.doctree.DocTree; 36 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; 37 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 38 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 40 import jdk.javadoc.internal.doclets.formats.html.markup.Links; 41 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 42 import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter; 43 import jdk.javadoc.internal.doclets.toolkit.Content; 44 import jdk.javadoc.internal.doclets.toolkit.builders.MemberSummaryBuilder; 45 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; 46 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; 47 import jdk.javadoc.internal.doclets.toolkit.util.DocPath; 48 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; 49 import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap; 50 51 /** 52 * Generate the Class Information Page. 53 * 54 * <p><b>This is NOT part of any supported API. 55 * If you write code that depends on this, you do so at your own risk. 56 * This code and its internal interfaces are subject to change or 57 * deletion without notice.</b> 58 * 59 * @see java.util.Collections 60 * @see java.util.List 61 * @see java.util.ArrayList 62 * @see java.util.HashMap 63 * 64 * @author Atul M Dambalkar 65 * @author Robert Field 66 * @author Bhavesh Patel (Modified) 67 */ 68 public class AnnotationTypeWriterImpl extends SubWriterHolderWriter 69 implements AnnotationTypeWriter { 70 71 protected TypeElement annotationType; 72 73 protected TypeMirror prev; 74 75 protected TypeMirror next; 76 77 /** 78 * @param configuration the configuration 79 * @param annotationType the annotation type being documented. 80 * @param prevType the previous class that was documented. 81 * @param nextType the next class being documented. 82 */ 83 public AnnotationTypeWriterImpl(HtmlConfiguration configuration, 84 TypeElement annotationType, TypeMirror prevType, TypeMirror nextType) { 85 super(configuration, DocPath.forClass(configuration.utils, annotationType)); 86 this.annotationType = annotationType; 87 configuration.currentTypeElement = annotationType; 88 this.prev = prevType; 89 this.next = nextType; 90 } 91 92 /** 93 * Get the module link. 94 * 95 * @return a content tree for the module link 96 */ 97 @Override 98 protected Content getNavLinkModule() { 99 Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(annotationType), 100 contents.moduleLabel); 101 Content li = HtmlTree.LI(linkContent); 102 return li; 103 } 104 105 /** 106 * Get this package link. 107 * 108 * @return a content tree for the package link 109 */ 110 @Override 111 protected Content getNavLinkPackage() { 112 Content linkContent = links.createLink(DocPaths.PACKAGE_SUMMARY, 113 contents.packageLabel); 114 Content li = HtmlTree.LI(linkContent); 115 return li; 116 } 117 118 /** 119 * Get the class link. 120 * 121 * @return a content tree for the class link 122 */ 123 @Override 124 protected Content getNavLinkClass() { 125 Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.classLabel); 126 return li; 127 } 128 129 /** 130 * Get the class use link. 131 * 132 * @return a content tree for the class use link 133 */ 134 @Override 135 protected Content getNavLinkClassUse() { 136 Content linkContent = links.createLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel); 137 Content li = HtmlTree.LI(linkContent); 138 return li; 139 } 140 141 /** 142 * Get link to previous class. 143 * 144 * @return a content tree for the previous class link 145 */ 146 @Override 147 public Content getNavLinkPrevious() { 148 Content li; 149 if (prev != null) { 150 Content prevLink = getLink(new LinkInfoImpl(configuration, 151 LinkInfoImpl.Kind.CLASS, utils.asTypeElement(prev)) 152 .label(contents.prevClassLabel).strong(true)); 153 li = HtmlTree.LI(prevLink); 154 } 155 else 156 li = HtmlTree.LI(contents.prevClassLabel); 157 return li; 158 } 159 160 /** 161 * Get link to next class. 162 * 163 * @return a content tree for the next class link 164 */ 165 @Override 166 public Content getNavLinkNext() { 167 Content li; 168 if (next != null) { 169 Content nextLink = getLink(new LinkInfoImpl(configuration, 170 LinkInfoImpl.Kind.CLASS, utils.asTypeElement(next)) 171 .label(contents.nextClassLabel).strong(true)); 172 li = HtmlTree.LI(nextLink); 173 } 174 else 175 li = HtmlTree.LI(contents.nextClassLabel); 176 return li; 177 } 178 179 /** 180 * {@inheritDoc} 181 */ 182 @Override 183 public Content getHeader(String header) { 184 HtmlTree bodyTree = getBody(true, getWindowTitle(utils.getSimpleName(annotationType))); 185 HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER)) 186 ? HtmlTree.HEADER() 187 : bodyTree; 188 addTop(htmlTree); 189 addNavLinks(true, htmlTree); 190 if (configuration.allowTag(HtmlTag.HEADER)) { 191 bodyTree.addContent(htmlTree); 192 } 193 bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA); 194 HtmlTree div = new HtmlTree(HtmlTag.DIV); 195 div.setStyle(HtmlStyle.header); 196 if (configuration.showModules) { 197 ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(annotationType); 198 Content typeModuleLabel = HtmlTree.SPAN(HtmlStyle.moduleLabelInType, contents.moduleLabel); 199 Content moduleNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, typeModuleLabel); 200 moduleNameDiv.addContent(Contents.SPACE); 201 moduleNameDiv.addContent(getModuleLink(mdle, new StringContent(mdle.getQualifiedName()))); 202 div.addContent(moduleNameDiv); 203 } 204 PackageElement pkg = utils.containingPackage(annotationType); 205 if (!pkg.isUnnamed()) { 206 Content typePackageLabel = HtmlTree.SPAN(HtmlStyle.packageLabelInType, contents.packageLabel); 207 Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, typePackageLabel); 208 pkgNameDiv.addContent(Contents.SPACE); 209 Content pkgNameContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))); 210 pkgNameDiv.addContent(pkgNameContent); 211 div.addContent(pkgNameDiv); 212 } 213 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 214 LinkInfoImpl.Kind.CLASS_HEADER, annotationType); 215 Content headerContent = new StringContent(header); 216 Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true, 217 HtmlStyle.title, headerContent); 218 heading.addContent(getTypeParameterLinks(linkInfo)); 219 div.addContent(heading); 220 if (configuration.allowTag(HtmlTag.MAIN)) { 221 mainTree.addContent(div); 222 } else { 223 bodyTree.addContent(div); 224 } 225 return bodyTree; 226 } 227 228 /** 229 * {@inheritDoc} 230 */ 231 @Override 232 public Content getAnnotationContentHeader() { 233 return getContentHeader(); 234 } 235 236 /** 237 * {@inheritDoc} 238 */ 239 @Override 240 public void addFooter(Content contentTree) { 241 contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA); 242 Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER)) 243 ? HtmlTree.FOOTER() 244 : contentTree; 245 addNavLinks(false, htmlTree); 246 addBottom(htmlTree); 247 if (configuration.allowTag(HtmlTag.FOOTER)) { 248 contentTree.addContent(htmlTree); 249 } 250 } 251 252 /** 253 * {@inheritDoc} 254 */ 255 @Override 256 public void printDocument(Content contentTree) throws DocFileIOException { 257 printHtmlDocument(configuration.metakeywords.getMetaKeywords(annotationType), 258 true, contentTree); 259 } 260 261 /** 262 * {@inheritDoc} 263 */ 264 @Override 265 public Content getAnnotationInfoTreeHeader() { 266 return getMemberTreeHeader(); 267 } 268 269 /** 270 * {@inheritDoc} 271 */ 272 @Override 273 public Content getAnnotationInfo(Content annotationInfoTree) { 274 return getMemberTree(HtmlStyle.description, annotationInfoTree); 275 } 276 277 /** 278 * {@inheritDoc} 279 */ 280 @Override 281 public void addAnnotationTypeSignature(String modifiers, Content annotationInfoTree) { 282 Content hr = new HtmlTree(HtmlTag.HR); 283 annotationInfoTree.addContent(hr); 284 Content pre = new HtmlTree(HtmlTag.PRE); 285 addAnnotationInfo(annotationType, pre); 286 pre.addContent(modifiers); 287 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 288 LinkInfoImpl.Kind.CLASS_SIGNATURE, annotationType); 289 Content annotationName = new StringContent(utils.getSimpleName(annotationType)); 290 Content parameterLinks = getTypeParameterLinks(linkInfo); 291 if (configuration.linksource) { 292 addSrcLink(annotationType, annotationName, pre); 293 pre.addContent(parameterLinks); 294 } else { 295 Content span = HtmlTree.SPAN(HtmlStyle.memberNameLabel, annotationName); 296 span.addContent(parameterLinks); 297 pre.addContent(span); 298 } 299 annotationInfoTree.addContent(pre); 300 } 301 302 /** 303 * {@inheritDoc} 304 */ 305 @Override 306 public void addAnnotationTypeDescription(Content annotationInfoTree) { 307 if (!configuration.nocomment) { 308 if (!utils.getFullBody(annotationType).isEmpty()) { 309 addInlineComment(annotationType, annotationInfoTree); 310 } 311 } 312 } 313 314 /** 315 * {@inheritDoc} 316 */ 317 @Override 318 public void addAnnotationTypeTagInfo(Content annotationInfoTree) { 319 if (!configuration.nocomment) { 320 addTagsInfo(annotationType, annotationInfoTree); 321 } 322 } 323 324 /** 325 * {@inheritDoc} 326 */ 327 @Override 328 public void addAnnotationTypeDeprecationInfo(Content annotationInfoTree) { 329 List<? extends DocTree> deprs = utils.getBlockTags(annotationType, DocTree.Kind.DEPRECATED); 330 if (utils.isDeprecated(annotationType)) { 331 CommentHelper ch = utils.getCommentHelper(annotationType); 332 Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(annotationType)); 333 Content div = HtmlTree.DIV(HtmlStyle.deprecationBlock, deprLabel); 334 if (!deprs.isEmpty()) { 335 336 List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0)); 337 if (!commentTags.isEmpty()) { 338 addInlineDeprecatedComment(annotationType, deprs.get(0), div); 339 } 340 } 341 annotationInfoTree.addContent(div); 342 } 343 } 344 345 /** 346 * {@inheritDoc} 347 */ 348 @Override 349 protected Content getNavLinkTree() { 350 Content treeLinkContent = links.createLink(DocPaths.PACKAGE_TREE, 351 contents.treeLabel, "", ""); 352 Content li = HtmlTree.LI(treeLinkContent); 353 return li; 354 } 355 356 /** 357 * Add summary details to the navigation bar. 358 * 359 * @param subDiv the content tree to which the summary detail links will be added 360 */ 361 @Override 362 protected void addSummaryDetailLinks(Content subDiv) { 363 Content div = HtmlTree.DIV(getNavSummaryLinks()); 364 div.addContent(getNavDetailLinks()); 365 subDiv.addContent(div); 366 } 367 368 /** 369 * Get summary links for navigation bar. 370 * 371 * @return the content tree for the navigation summary links 372 */ 373 protected Content getNavSummaryLinks() { 374 Content li = HtmlTree.LI(contents.summaryLabel); 375 li.addContent(Contents.SPACE); 376 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); 377 MemberSummaryBuilder memberSummaryBuilder = 378 configuration.getBuilderFactory().getMemberSummaryBuilder(this); 379 Content liNavField = new HtmlTree(HtmlTag.LI); 380 addNavSummaryLink(memberSummaryBuilder, 381 "doclet.navField", 382 VisibleMemberMap.Kind.ANNOTATION_TYPE_FIELDS, liNavField); 383 addNavGap(liNavField); 384 ulNav.addContent(liNavField); 385 Content liNavReq = new HtmlTree(HtmlTag.LI); 386 addNavSummaryLink(memberSummaryBuilder, 387 "doclet.navAnnotationTypeRequiredMember", 388 VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_REQUIRED, liNavReq); 389 addNavGap(liNavReq); 390 ulNav.addContent(liNavReq); 391 Content liNavOpt = new HtmlTree(HtmlTag.LI); 392 addNavSummaryLink(memberSummaryBuilder, 393 "doclet.navAnnotationTypeOptionalMember", 394 VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL, liNavOpt); 395 ulNav.addContent(liNavOpt); 396 return ulNav; 397 } 398 399 /** 400 * Add the navigation summary link. 401 * 402 * @param builder builder for the member to be documented 403 * @param label the label for the navigation 404 * @param type type to be documented 405 * @param liNav the content tree to which the navigation summary link will be added 406 */ 407 protected void addNavSummaryLink(MemberSummaryBuilder builder, 408 String label, VisibleMemberMap.Kind type, Content liNav) { 409 AbstractMemberWriter writer = ((AbstractMemberWriter) builder. 410 getMemberSummaryWriter(type)); 411 if (writer == null) { 412 liNav.addContent(contents.getContent(label)); 413 } else { 414 liNav.addContent(writer.getNavSummaryLink(null, 415 ! builder.getVisibleMemberMap(type).noVisibleMembers())); 416 } 417 } 418 419 /** 420 * Get detail links for the navigation bar. 421 * 422 * @return the content tree for the detail links 423 */ 424 protected Content getNavDetailLinks() { 425 Content li = HtmlTree.LI(contents.detailLabel); 426 li.addContent(Contents.SPACE); 427 Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); 428 MemberSummaryBuilder memberSummaryBuilder = 429 configuration.getBuilderFactory().getMemberSummaryBuilder(this); 430 AbstractMemberWriter writerField = 431 ((AbstractMemberWriter) memberSummaryBuilder. 432 getMemberSummaryWriter(VisibleMemberMap.Kind.ANNOTATION_TYPE_FIELDS)); 433 AbstractMemberWriter writerOptional = 434 ((AbstractMemberWriter) memberSummaryBuilder. 435 getMemberSummaryWriter(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL)); 436 AbstractMemberWriter writerRequired = 437 ((AbstractMemberWriter) memberSummaryBuilder. 438 getMemberSummaryWriter(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_REQUIRED)); 439 Content liNavField = new HtmlTree(HtmlTag.LI); 440 if (writerField != null) { 441 writerField.addNavDetailLink(!utils.getAnnotationFields(annotationType).isEmpty(), liNavField); 442 } else { 443 liNavField.addContent(contents.navField); 444 } 445 addNavGap(liNavField); 446 ulNav.addContent(liNavField); 447 if (writerOptional != null){ 448 Content liNavOpt = new HtmlTree(HtmlTag.LI); 449 writerOptional.addNavDetailLink(!annotationType.getAnnotationMirrors().isEmpty(), liNavOpt); 450 ulNav.addContent(liNavOpt); 451 } else if (writerRequired != null){ 452 Content liNavReq = new HtmlTree(HtmlTag.LI); 453 writerRequired.addNavDetailLink(!annotationType.getAnnotationMirrors().isEmpty(), liNavReq); 454 ulNav.addContent(liNavReq); 455 } else { 456 Content liNav = HtmlTree.LI(contents.navAnnotationTypeMember); 457 ulNav.addContent(liNav); 458 } 459 return ulNav; 460 } 461 462 /** 463 * {@inheritDoc} 464 */ 465 @Override 466 public TypeElement getAnnotationTypeElement() { 467 return annotationType; 468 } 469 }