aoqi@0: /* aoqi@0: * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.tools.doclets.formats.html; aoqi@0: aoqi@0: import java.io.IOException; aoqi@0: aoqi@0: import com.sun.javadoc.*; aoqi@0: import com.sun.tools.doclets.formats.html.markup.*; aoqi@0: import com.sun.tools.doclets.internal.toolkit.*; aoqi@0: import com.sun.tools.doclets.internal.toolkit.builders.*; aoqi@0: import com.sun.tools.doclets.internal.toolkit.util.*; aoqi@0: aoqi@0: /** aoqi@0: * Generate the Class Information Page. aoqi@0: * aoqi@0: *

This is NOT part of any supported API. aoqi@0: * If you write code that depends on this, you do so at your own risk. aoqi@0: * This code and its internal interfaces are subject to change or aoqi@0: * deletion without notice. aoqi@0: * aoqi@0: * @see com.sun.javadoc.ClassDoc aoqi@0: * @see java.util.Collections aoqi@0: * @see java.util.List aoqi@0: * @see java.util.ArrayList aoqi@0: * @see java.util.HashMap aoqi@0: * aoqi@0: * @author Atul M Dambalkar aoqi@0: * @author Robert Field aoqi@0: * @author Bhavesh Patel (Modified) aoqi@0: */ aoqi@0: public class AnnotationTypeWriterImpl extends SubWriterHolderWriter aoqi@0: implements AnnotationTypeWriter { aoqi@0: aoqi@0: protected AnnotationTypeDoc annotationType; aoqi@0: aoqi@0: protected Type prev; aoqi@0: aoqi@0: protected Type next; aoqi@0: aoqi@0: /** aoqi@0: * @param annotationType the annotation type being documented. aoqi@0: * @param prevType the previous class that was documented. aoqi@0: * @param nextType the next class being documented. aoqi@0: */ aoqi@0: public AnnotationTypeWriterImpl(ConfigurationImpl configuration, aoqi@0: AnnotationTypeDoc annotationType, Type prevType, Type nextType) aoqi@0: throws Exception { aoqi@0: super(configuration, DocPath.forClass(annotationType)); aoqi@0: this.annotationType = annotationType; aoqi@0: configuration.currentcd = annotationType.asClassDoc(); aoqi@0: this.prev = prevType; aoqi@0: this.next = nextType; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get this package link. aoqi@0: * aoqi@0: * @return a content tree for the package link aoqi@0: */ aoqi@0: protected Content getNavLinkPackage() { aoqi@0: Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY, aoqi@0: packageLabel); aoqi@0: Content li = HtmlTree.LI(linkContent); aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the class link. aoqi@0: * aoqi@0: * @return a content tree for the class link aoqi@0: */ aoqi@0: protected Content getNavLinkClass() { aoqi@0: Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, classLabel); aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the class use link. aoqi@0: * aoqi@0: * @return a content tree for the class use link aoqi@0: */ aoqi@0: protected Content getNavLinkClassUse() { aoqi@0: Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), useLabel); aoqi@0: Content li = HtmlTree.LI(linkContent); aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get link to previous class. aoqi@0: * aoqi@0: * @return a content tree for the previous class link aoqi@0: */ aoqi@0: public Content getNavLinkPrevious() { aoqi@0: Content li; aoqi@0: if (prev != null) { aoqi@0: Content prevLink = getLink(new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS, prev.asClassDoc()) aoqi@0: .label(prevclassLabel).strong(true)); aoqi@0: li = HtmlTree.LI(prevLink); aoqi@0: } aoqi@0: else aoqi@0: li = HtmlTree.LI(prevclassLabel); aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get link to next class. aoqi@0: * aoqi@0: * @return a content tree for the next class link aoqi@0: */ aoqi@0: public Content getNavLinkNext() { aoqi@0: Content li; aoqi@0: if (next != null) { aoqi@0: Content nextLink = getLink(new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS, next.asClassDoc()) aoqi@0: .label(nextclassLabel).strong(true)); aoqi@0: li = HtmlTree.LI(nextLink); aoqi@0: } aoqi@0: else aoqi@0: li = HtmlTree.LI(nextclassLabel); aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public Content getHeader(String header) { aoqi@0: String pkgname = (annotationType.containingPackage() != null)? aoqi@0: annotationType.containingPackage().name(): ""; aoqi@0: String clname = annotationType.name(); aoqi@0: Content bodyTree = getBody(true, getWindowTitle(clname)); aoqi@0: addTop(bodyTree); aoqi@0: addNavLinks(true, bodyTree); aoqi@0: bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA); aoqi@0: HtmlTree div = new HtmlTree(HtmlTag.DIV); aoqi@0: div.addStyle(HtmlStyle.header); aoqi@0: if (pkgname.length() > 0) { aoqi@0: Content pkgNameContent = new StringContent(pkgname); aoqi@0: Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent); aoqi@0: div.addContent(pkgNameDiv); aoqi@0: } aoqi@0: LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS_HEADER, annotationType); aoqi@0: Content headerContent = new StringContent(header); aoqi@0: Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true, aoqi@0: HtmlStyle.title, headerContent); aoqi@0: heading.addContent(getTypeParameterLinks(linkInfo)); aoqi@0: div.addContent(heading); aoqi@0: bodyTree.addContent(div); aoqi@0: return bodyTree; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public Content getAnnotationContentHeader() { aoqi@0: return getContentHeader(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addFooter(Content contentTree) { aoqi@0: contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA); aoqi@0: addNavLinks(false, contentTree); aoqi@0: addBottom(contentTree); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void printDocument(Content contentTree) throws IOException { aoqi@0: printHtmlDocument(configuration.metakeywords.getMetaKeywords(annotationType), aoqi@0: true, contentTree); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public Content getAnnotationInfoTreeHeader() { aoqi@0: return getMemberTreeHeader(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public Content getAnnotationInfo(Content annotationInfoTree) { aoqi@0: return getMemberTree(HtmlStyle.description, annotationInfoTree); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addAnnotationTypeSignature(String modifiers, Content annotationInfoTree) { aoqi@0: annotationInfoTree.addContent(new HtmlTree(HtmlTag.BR)); aoqi@0: Content pre = new HtmlTree(HtmlTag.PRE); aoqi@0: addAnnotationInfo(annotationType, pre); aoqi@0: pre.addContent(modifiers); aoqi@0: LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS_SIGNATURE, annotationType); aoqi@0: Content annotationName = new StringContent(annotationType.name()); aoqi@0: Content parameterLinks = getTypeParameterLinks(linkInfo); aoqi@0: if (configuration.linksource) { aoqi@0: addSrcLink(annotationType, annotationName, pre); aoqi@0: pre.addContent(parameterLinks); aoqi@0: } else { aoqi@0: Content span = HtmlTree.SPAN(HtmlStyle.memberNameLabel, annotationName); aoqi@0: span.addContent(parameterLinks); aoqi@0: pre.addContent(span); aoqi@0: } aoqi@0: annotationInfoTree.addContent(pre); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addAnnotationTypeDescription(Content annotationInfoTree) { aoqi@0: if(!configuration.nocomment) { aoqi@0: if (annotationType.inlineTags().length > 0) { aoqi@0: addInlineComment(annotationType, annotationInfoTree); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addAnnotationTypeTagInfo(Content annotationInfoTree) { aoqi@0: if(!configuration.nocomment) { aoqi@0: addTagsInfo(annotationType, annotationInfoTree); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addAnnotationTypeDeprecationInfo(Content annotationInfoTree) { aoqi@0: Content hr = new HtmlTree(HtmlTag.HR); aoqi@0: annotationInfoTree.addContent(hr); aoqi@0: Tag[] deprs = annotationType.tags("deprecated"); aoqi@0: if (Util.isDeprecated(annotationType)) { aoqi@0: Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, deprecatedPhrase); aoqi@0: Content div = HtmlTree.DIV(HtmlStyle.block, deprLabel); aoqi@0: if (deprs.length > 0) { aoqi@0: Tag[] commentTags = deprs[0].inlineTags(); aoqi@0: if (commentTags.length > 0) { aoqi@0: div.addContent(getSpace()); aoqi@0: addInlineDeprecatedComment(annotationType, deprs[0], div); aoqi@0: } aoqi@0: } aoqi@0: annotationInfoTree.addContent(div); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: protected Content getNavLinkTree() { aoqi@0: Content treeLinkContent = getHyperLink(DocPaths.PACKAGE_TREE, aoqi@0: treeLabel, "", ""); aoqi@0: Content li = HtmlTree.LI(treeLinkContent); aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Add summary details to the navigation bar. aoqi@0: * aoqi@0: * @param subDiv the content tree to which the summary detail links will be added aoqi@0: */ aoqi@0: protected void addSummaryDetailLinks(Content subDiv) { aoqi@0: try { aoqi@0: Content div = HtmlTree.DIV(getNavSummaryLinks()); aoqi@0: div.addContent(getNavDetailLinks()); aoqi@0: subDiv.addContent(div); aoqi@0: } catch (Exception e) { aoqi@0: e.printStackTrace(); aoqi@0: throw new DocletAbortException(e); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get summary links for navigation bar. aoqi@0: * aoqi@0: * @return the content tree for the navigation summary links aoqi@0: */ aoqi@0: protected Content getNavSummaryLinks() throws Exception { aoqi@0: Content li = HtmlTree.LI(summaryLabel); aoqi@0: li.addContent(getSpace()); aoqi@0: Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); aoqi@0: MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) aoqi@0: configuration.getBuilderFactory().getMemberSummaryBuilder(this); aoqi@0: Content liNavField = new HtmlTree(HtmlTag.LI); aoqi@0: addNavSummaryLink(memberSummaryBuilder, aoqi@0: "doclet.navField", aoqi@0: VisibleMemberMap.ANNOTATION_TYPE_FIELDS, liNavField); aoqi@0: addNavGap(liNavField); aoqi@0: ulNav.addContent(liNavField); aoqi@0: Content liNavReq = new HtmlTree(HtmlTag.LI); aoqi@0: addNavSummaryLink(memberSummaryBuilder, aoqi@0: "doclet.navAnnotationTypeRequiredMember", aoqi@0: VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED, liNavReq); aoqi@0: addNavGap(liNavReq); aoqi@0: ulNav.addContent(liNavReq); aoqi@0: Content liNavOpt = new HtmlTree(HtmlTag.LI); aoqi@0: addNavSummaryLink(memberSummaryBuilder, aoqi@0: "doclet.navAnnotationTypeOptionalMember", aoqi@0: VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL, liNavOpt); aoqi@0: ulNav.addContent(liNavOpt); aoqi@0: return ulNav; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Add the navigation summary link. aoqi@0: * aoqi@0: * @param builder builder for the member to be documented aoqi@0: * @param label the label for the navigation aoqi@0: * @param type type to be documented aoqi@0: * @param liNav the content tree to which the navigation summary link will be added aoqi@0: */ aoqi@0: protected void addNavSummaryLink(MemberSummaryBuilder builder, aoqi@0: String label, int type, Content liNav) { aoqi@0: AbstractMemberWriter writer = ((AbstractMemberWriter) builder. aoqi@0: getMemberSummaryWriter(type)); aoqi@0: if (writer == null) { aoqi@0: liNav.addContent(getResource(label)); aoqi@0: } else { aoqi@0: liNav.addContent(writer.getNavSummaryLink(null, aoqi@0: ! builder.getVisibleMemberMap(type).noVisibleMembers())); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get detail links for the navigation bar. aoqi@0: * aoqi@0: * @return the content tree for the detail links aoqi@0: */ aoqi@0: protected Content getNavDetailLinks() throws Exception { aoqi@0: Content li = HtmlTree.LI(detailLabel); aoqi@0: li.addContent(getSpace()); aoqi@0: Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li); aoqi@0: MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder) aoqi@0: configuration.getBuilderFactory().getMemberSummaryBuilder(this); aoqi@0: AbstractMemberWriter writerField = aoqi@0: ((AbstractMemberWriter) memberSummaryBuilder. aoqi@0: getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_FIELDS)); aoqi@0: AbstractMemberWriter writerOptional = aoqi@0: ((AbstractMemberWriter) memberSummaryBuilder. aoqi@0: getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL)); aoqi@0: AbstractMemberWriter writerRequired = aoqi@0: ((AbstractMemberWriter) memberSummaryBuilder. aoqi@0: getMemberSummaryWriter(VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED)); aoqi@0: Content liNavField = new HtmlTree(HtmlTag.LI); aoqi@0: if (writerField != null){ aoqi@0: writerField.addNavDetailLink(annotationType.fields().length > 0, liNavField); aoqi@0: } else { aoqi@0: liNavField.addContent(getResource("doclet.navField")); aoqi@0: } aoqi@0: addNavGap(liNavField); aoqi@0: ulNav.addContent(liNavField); aoqi@0: if (writerOptional != null){ aoqi@0: Content liNavOpt = new HtmlTree(HtmlTag.LI); aoqi@0: writerOptional.addNavDetailLink(annotationType.elements().length > 0, liNavOpt); aoqi@0: ulNav.addContent(liNavOpt); aoqi@0: } else if (writerRequired != null){ aoqi@0: Content liNavReq = new HtmlTree(HtmlTag.LI); aoqi@0: writerRequired.addNavDetailLink(annotationType.elements().length > 0, liNavReq); aoqi@0: ulNav.addContent(liNavReq); aoqi@0: } else { aoqi@0: Content liNav = HtmlTree.LI(getResource("doclet.navAnnotationTypeMember")); aoqi@0: ulNav.addContent(liNav); aoqi@0: } aoqi@0: return ulNav; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Add gap between navigation bar elements. aoqi@0: * aoqi@0: * @param liNav the content tree to which the gap will be added aoqi@0: */ aoqi@0: protected void addNavGap(Content liNav) { aoqi@0: liNav.addContent(getSpace()); aoqi@0: liNav.addContent("|"); aoqi@0: liNav.addContent(getSpace()); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public AnnotationTypeDoc getAnnotationTypeDoc() { aoqi@0: return annotationType; aoqi@0: } aoqi@0: }