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