aoqi@0: /* aoqi@0: * Copyright (c) 1997, 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.util.*; aoqi@0: aoqi@0: import com.sun.javadoc.*; aoqi@0: import com.sun.tools.javac.jvm.Profile; aoqi@0: import com.sun.tools.javadoc.RootDocImpl; 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.taglets.*; aoqi@0: import com.sun.tools.doclets.internal.toolkit.util.*; aoqi@0: import java.io.IOException; 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 ClassWriterImpl extends SubWriterHolderWriter aoqi@0: implements ClassWriter { aoqi@0: aoqi@0: protected final ClassDoc classDoc; aoqi@0: aoqi@0: protected final ClassTree classtree; aoqi@0: aoqi@0: protected final ClassDoc prev; aoqi@0: aoqi@0: protected final ClassDoc next; aoqi@0: aoqi@0: /** aoqi@0: * @param configuration the configuration data for the doclet aoqi@0: * @param classDoc the class being documented. aoqi@0: * @param prevClass the previous class that was documented. aoqi@0: * @param nextClass the next class being documented. aoqi@0: * @param classTree the class tree for the given class. aoqi@0: */ aoqi@0: public ClassWriterImpl (ConfigurationImpl configuration, ClassDoc classDoc, aoqi@0: ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree) aoqi@0: throws IOException { aoqi@0: super(configuration, DocPath.forClass(classDoc)); aoqi@0: this.classDoc = classDoc; aoqi@0: configuration.currentcd = classDoc; aoqi@0: this.classtree = classTree; aoqi@0: this.prev = prevClass; aoqi@0: this.next = nextClass; 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) 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) 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 = (classDoc.containingPackage() != null)? aoqi@0: classDoc.containingPackage().name(): ""; aoqi@0: String clname = classDoc.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 (configuration.showProfiles) { aoqi@0: String sep = ""; aoqi@0: int profile = configuration.profiles.getProfile(getTypeNameForProfile(classDoc)); aoqi@0: if (profile > 0) { aoqi@0: Content profNameContent = new StringContent(); aoqi@0: for (int i = profile; i < configuration.profiles.getProfileCount(); i++) { aoqi@0: profNameContent.addContent(sep); aoqi@0: profNameContent.addContent(Profile.lookup(i).name); aoqi@0: sep = ", "; aoqi@0: } aoqi@0: Content profileNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, profNameContent); aoqi@0: div.addContent(profileNameDiv); aoqi@0: } aoqi@0: } 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, classDoc); aoqi@0: //Let's not link to ourselves in the header. aoqi@0: linkInfo.linkToSelf = false; 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 getClassContentHeader() { 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(classDoc), aoqi@0: true, contentTree); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public Content getClassInfoTreeHeader() { aoqi@0: return getMemberTreeHeader(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public Content getClassInfo(Content classInfoTree) { aoqi@0: return getMemberTree(HtmlStyle.description, classInfoTree); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addClassSignature(String modifiers, Content classInfoTree) { aoqi@0: boolean isInterface = classDoc.isInterface(); aoqi@0: classInfoTree.addContent(new HtmlTree(HtmlTag.BR)); aoqi@0: Content pre = new HtmlTree(HtmlTag.PRE); aoqi@0: addAnnotationInfo(classDoc, pre); aoqi@0: pre.addContent(modifiers); aoqi@0: LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS_SIGNATURE, classDoc); aoqi@0: //Let's not link to ourselves in the signature. aoqi@0: linkInfo.linkToSelf = false; aoqi@0: Content className = new StringContent(classDoc.name()); aoqi@0: Content parameterLinks = getTypeParameterLinks(linkInfo); aoqi@0: if (configuration.linksource) { aoqi@0: addSrcLink(classDoc, className, pre); aoqi@0: pre.addContent(parameterLinks); aoqi@0: } else { aoqi@0: Content span = HtmlTree.SPAN(HtmlStyle.typeNameLabel, className); aoqi@0: span.addContent(parameterLinks); aoqi@0: pre.addContent(span); aoqi@0: } aoqi@0: if (!isInterface) { aoqi@0: Type superclass = Util.getFirstVisibleSuperClass(classDoc, aoqi@0: configuration); aoqi@0: if (superclass != null) { aoqi@0: pre.addContent(DocletConstants.NL); aoqi@0: pre.addContent("extends "); aoqi@0: Content link = getLink(new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, aoqi@0: superclass)); aoqi@0: pre.addContent(link); aoqi@0: } aoqi@0: } aoqi@0: Type[] implIntfacs = classDoc.interfaceTypes(); aoqi@0: if (implIntfacs != null && implIntfacs.length > 0) { aoqi@0: int counter = 0; aoqi@0: for (int i = 0; i < implIntfacs.length; i++) { aoqi@0: ClassDoc classDoc = implIntfacs[i].asClassDoc(); aoqi@0: if (! (classDoc.isPublic() || aoqi@0: Util.isLinkable(classDoc, configuration))) { aoqi@0: continue; aoqi@0: } aoqi@0: if (counter == 0) { aoqi@0: pre.addContent(DocletConstants.NL); aoqi@0: pre.addContent(isInterface? "extends " : "implements "); aoqi@0: } else { aoqi@0: pre.addContent(", "); aoqi@0: } aoqi@0: Content link = getLink(new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, aoqi@0: implIntfacs[i])); aoqi@0: pre.addContent(link); aoqi@0: counter++; aoqi@0: } aoqi@0: } aoqi@0: classInfoTree.addContent(pre); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addClassDescription(Content classInfoTree) { aoqi@0: if(!configuration.nocomment) { aoqi@0: // generate documentation for the class. aoqi@0: if (classDoc.inlineTags().length > 0) { aoqi@0: addInlineComment(classDoc, classInfoTree); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addClassTagInfo(Content classInfoTree) { aoqi@0: if(!configuration.nocomment) { aoqi@0: // Print Information about all the tags here aoqi@0: addTagsInfo(classDoc, classInfoTree); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the class hierarchy tree for the given class. aoqi@0: * aoqi@0: * @param type the class to print the hierarchy for aoqi@0: * @return a content tree for class inheritence aoqi@0: */ aoqi@0: private Content getClassInheritenceTree(Type type) { aoqi@0: Type sup; aoqi@0: HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL); aoqi@0: classTreeUl.addStyle(HtmlStyle.inheritance); aoqi@0: Content liTree = null; aoqi@0: do { aoqi@0: sup = Util.getFirstVisibleSuperClass( aoqi@0: type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(), aoqi@0: configuration); aoqi@0: if (sup != null) { aoqi@0: HtmlTree ul = new HtmlTree(HtmlTag.UL); aoqi@0: ul.addStyle(HtmlStyle.inheritance); aoqi@0: ul.addContent(getTreeForClassHelper(type)); aoqi@0: if (liTree != null) aoqi@0: ul.addContent(liTree); aoqi@0: Content li = HtmlTree.LI(ul); aoqi@0: liTree = li; aoqi@0: type = sup; aoqi@0: } aoqi@0: else aoqi@0: classTreeUl.addContent(getTreeForClassHelper(type)); aoqi@0: } aoqi@0: while (sup != null); aoqi@0: if (liTree != null) aoqi@0: classTreeUl.addContent(liTree); aoqi@0: return classTreeUl; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the class helper tree for the given class. aoqi@0: * aoqi@0: * @param type the class to print the helper for aoqi@0: * @return a content tree for class helper aoqi@0: */ aoqi@0: private Content getTreeForClassHelper(Type type) { aoqi@0: Content li = new HtmlTree(HtmlTag.LI); aoqi@0: if (type.equals(classDoc)) { aoqi@0: Content typeParameters = getTypeParameterLinks( aoqi@0: new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE, aoqi@0: classDoc)); aoqi@0: if (configuration.shouldExcludeQualifier( aoqi@0: classDoc.containingPackage().name())) { aoqi@0: li.addContent(type.asClassDoc().name()); aoqi@0: li.addContent(typeParameters); aoqi@0: } else { aoqi@0: li.addContent(type.asClassDoc().qualifiedName()); aoqi@0: li.addContent(typeParameters); aoqi@0: } aoqi@0: } else { aoqi@0: Content link = getLink(new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS_TREE_PARENT, type) aoqi@0: .label(configuration.getClassName(type.asClassDoc()))); aoqi@0: li.addContent(link); aoqi@0: } aoqi@0: return li; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addClassTree(Content classContentTree) { aoqi@0: if (!classDoc.isClass()) { aoqi@0: return; aoqi@0: } aoqi@0: classContentTree.addContent(getClassInheritenceTree(classDoc)); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addTypeParamInfo(Content classInfoTree) { aoqi@0: if (classDoc.typeParamTags().length > 0) { aoqi@0: Content typeParam = (new ParamTaglet()).getTagletOutput(classDoc, aoqi@0: getTagletWriterInstance(false)); aoqi@0: Content dl = HtmlTree.DL(typeParam); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addSubClassInfo(Content classInfoTree) { aoqi@0: if (classDoc.isClass()) { aoqi@0: if (classDoc.qualifiedName().equals("java.lang.Object") || aoqi@0: classDoc.qualifiedName().equals("org.omg.CORBA.Object")) { aoqi@0: return; // Don't generate the list, too huge aoqi@0: } aoqi@0: List subclasses = classtree.subs(classDoc, false); aoqi@0: if (subclasses.size() > 0) { aoqi@0: Content label = getResource( aoqi@0: "doclet.Subclasses"); aoqi@0: Content dt = HtmlTree.DT(label); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES, aoqi@0: subclasses)); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addSubInterfacesInfo(Content classInfoTree) { aoqi@0: if (classDoc.isInterface()) { aoqi@0: List subInterfaces = classtree.allSubs(classDoc, false); aoqi@0: if (subInterfaces.size() > 0) { aoqi@0: Content label = getResource( aoqi@0: "doclet.Subinterfaces"); aoqi@0: Content dt = HtmlTree.DT(label); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES, aoqi@0: subInterfaces)); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addInterfaceUsageInfo (Content classInfoTree) { aoqi@0: if (! classDoc.isInterface()) { aoqi@0: return; aoqi@0: } aoqi@0: if (classDoc.qualifiedName().equals("java.lang.Cloneable") || aoqi@0: classDoc.qualifiedName().equals("java.io.Serializable")) { aoqi@0: return; // Don't generate the list, too big aoqi@0: } aoqi@0: List implcl = classtree.implementingclasses(classDoc); aoqi@0: if (implcl.size() > 0) { aoqi@0: Content label = getResource( aoqi@0: "doclet.Implementing_Classes"); aoqi@0: Content dt = HtmlTree.DT(label); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES, aoqi@0: implcl)); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addImplementedInterfacesInfo(Content classInfoTree) { aoqi@0: //NOTE: we really should be using ClassDoc.interfaceTypes() here, but aoqi@0: // it doesn't walk up the tree like we want it to. aoqi@0: List interfaceArray = Util.getAllInterfaces(classDoc, configuration); aoqi@0: if (classDoc.isClass() && interfaceArray.size() > 0) { aoqi@0: Content label = getResource( aoqi@0: "doclet.All_Implemented_Interfaces"); aoqi@0: Content dt = HtmlTree.DT(label); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: dl.addContent(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES, aoqi@0: interfaceArray)); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addSuperInterfacesInfo(Content classInfoTree) { aoqi@0: //NOTE: we really should be using ClassDoc.interfaceTypes() here, but aoqi@0: // it doesn't walk up the tree like we want it to. aoqi@0: List interfaceArray = Util.getAllInterfaces(classDoc, configuration); aoqi@0: if (classDoc.isInterface() && interfaceArray.size() > 0) { aoqi@0: Content label = getResource( aoqi@0: "doclet.All_Superinterfaces"); aoqi@0: Content dt = HtmlTree.DT(label); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: dl.addContent(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES, aoqi@0: interfaceArray)); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addNestedClassInfo(Content classInfoTree) { aoqi@0: ClassDoc outerClass = classDoc.containingClass(); aoqi@0: if (outerClass != null) { aoqi@0: Content label; aoqi@0: if (outerClass.isInterface()) { aoqi@0: label = getResource( aoqi@0: "doclet.Enclosing_Interface"); aoqi@0: } else { aoqi@0: label = getResource( aoqi@0: "doclet.Enclosing_Class"); aoqi@0: } aoqi@0: Content dt = HtmlTree.DT(label); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: Content dd = new HtmlTree(HtmlTag.DD); aoqi@0: dd.addContent(getLink(new LinkInfoImpl(configuration, aoqi@0: LinkInfoImpl.Kind.CLASS, outerClass))); aoqi@0: dl.addContent(dd); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addFunctionalInterfaceInfo (Content classInfoTree) { aoqi@0: if (isFunctionalInterface()) { aoqi@0: Content dt = HtmlTree.DT(getResource("doclet.Functional_Interface")); aoqi@0: Content dl = HtmlTree.DL(dt); aoqi@0: Content dd = new HtmlTree(HtmlTag.DD); aoqi@0: dd.addContent(getResource("doclet.Functional_Interface_Message")); aoqi@0: dl.addContent(dd); aoqi@0: classInfoTree.addContent(dl); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: public boolean isFunctionalInterface() { aoqi@0: if (configuration.root instanceof RootDocImpl) { aoqi@0: RootDocImpl root = (RootDocImpl) configuration.root; aoqi@0: AnnotationDesc[] annotationDescList = classDoc.annotations(); aoqi@0: for (AnnotationDesc annoDesc : annotationDescList) { aoqi@0: if (root.isFunctionalInterface(annoDesc)) { aoqi@0: return true; aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * {@inheritDoc} aoqi@0: */ aoqi@0: public void addClassDeprecationInfo(Content classInfoTree) { aoqi@0: Content hr = new HtmlTree(HtmlTag.HR); aoqi@0: classInfoTree.addContent(hr); aoqi@0: Tag[] deprs = classDoc.tags("deprecated"); aoqi@0: if (Util.isDeprecated(classDoc)) { 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(classDoc, deprs[0], div); aoqi@0: } aoqi@0: } aoqi@0: classInfoTree.addContent(div); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get links to the given classes. aoqi@0: * aoqi@0: * @param context the id of the context where the link will be printed aoqi@0: * @param list the list of classes aoqi@0: * @return a content tree for the class list aoqi@0: */ aoqi@0: private Content getClassLinks(LinkInfoImpl.Kind context, List list) { aoqi@0: Object[] typeList = list.toArray(); aoqi@0: Content dd = new HtmlTree(HtmlTag.DD); aoqi@0: for (int i = 0; i < list.size(); i++) { aoqi@0: if (i > 0) { aoqi@0: Content separator = new StringContent(", "); aoqi@0: dd.addContent(separator); aoqi@0: } aoqi@0: if (typeList[i] instanceof ClassDoc) { aoqi@0: Content link = getLink( aoqi@0: new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i]))); aoqi@0: dd.addContent(link); aoqi@0: } else { aoqi@0: Content link = getLink( aoqi@0: new LinkInfoImpl(configuration, context, (Type)(typeList[i]))); aoqi@0: dd.addContent(link); aoqi@0: } aoqi@0: } aoqi@0: return dd; 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: String[] navLinkLabels = new String[] { aoqi@0: "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor", aoqi@0: "doclet.navMethod" aoqi@0: }; aoqi@0: for (int i = 0; i < navLinkLabels.length; i++ ) { aoqi@0: Content liNav = new HtmlTree(HtmlTag.LI); aoqi@0: if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) { aoqi@0: continue; aoqi@0: } aoqi@0: if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) { aoqi@0: continue; aoqi@0: } aoqi@0: AbstractMemberWriter writer = aoqi@0: ((AbstractMemberWriter) memberSummaryBuilder. aoqi@0: getMemberSummaryWriter(i)); aoqi@0: if (writer == null) { aoqi@0: liNav.addContent(getResource(navLinkLabels[i])); aoqi@0: } else { aoqi@0: writer.addNavSummaryLink( aoqi@0: memberSummaryBuilder.members(i), aoqi@0: memberSummaryBuilder.getVisibleMemberMap(i), liNav); aoqi@0: } aoqi@0: if (i < navLinkLabels.length-1) { aoqi@0: addNavGap(liNav); aoqi@0: } aoqi@0: ulNav.addContent(liNav); aoqi@0: } aoqi@0: return ulNav; 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: String[] navLinkLabels = new String[] { aoqi@0: "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor", aoqi@0: "doclet.navMethod" aoqi@0: }; aoqi@0: for (int i = 1; i < navLinkLabels.length; i++ ) { aoqi@0: Content liNav = new HtmlTree(HtmlTag.LI); aoqi@0: AbstractMemberWriter writer = aoqi@0: ((AbstractMemberWriter) memberSummaryBuilder. aoqi@0: getMemberSummaryWriter(i)); aoqi@0: if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) { aoqi@0: continue; aoqi@0: } aoqi@0: if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) { aoqi@0: continue; aoqi@0: } aoqi@0: if (writer == null) { aoqi@0: liNav.addContent(getResource(navLinkLabels[i])); aoqi@0: } else { aoqi@0: writer.addNavDetailLink(memberSummaryBuilder.members(i), liNav); aoqi@0: } aoqi@0: if (i < navLinkLabels.length - 1) { aoqi@0: addNavGap(liNav); aoqi@0: } 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: * Return the classDoc being documented. aoqi@0: * aoqi@0: * @return the classDoc being documented. aoqi@0: */ aoqi@0: public ClassDoc getClassDoc() { aoqi@0: return classDoc; aoqi@0: } aoqi@0: }