duke@1: /* bpatel@1568: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@554: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@554: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: package com.sun.tools.doclets.formats.html; duke@1: bpatel@233: import java.util.*; bpatel@233: bpatel@233: import com.sun.javadoc.*; bpatel@1568: import com.sun.tools.javac.jvm.Profile; jjg@1357: import com.sun.tools.doclets.formats.html.markup.*; duke@1: import com.sun.tools.doclets.internal.toolkit.*; duke@1: import com.sun.tools.doclets.internal.toolkit.builders.*; duke@1: import com.sun.tools.doclets.internal.toolkit.taglets.*; jjg@1357: import com.sun.tools.doclets.internal.toolkit.util.*; jjg@1410: import java.io.IOException; duke@1: duke@1: /** duke@1: * Generate the Class Information Page. jjg@1359: * jjg@1359: *
This is NOT part of any supported API.
jjg@1359: * If you write code that depends on this, you do so at your own risk.
jjg@1359: * This code and its internal interfaces are subject to change or
jjg@1359: * deletion without notice.
jjg@1359: *
duke@1: * @see com.sun.javadoc.ClassDoc
duke@1: * @see java.util.Collections
duke@1: * @see java.util.List
duke@1: * @see java.util.ArrayList
duke@1: * @see java.util.HashMap
duke@1: *
duke@1: * @author Atul M Dambalkar
duke@1: * @author Robert Field
bpatel@766: * @author Bhavesh Patel (Modified)
duke@1: */
duke@1: public class ClassWriterImpl extends SubWriterHolderWriter
duke@1: implements ClassWriter {
duke@1:
jjg@1410: protected final ClassDoc classDoc;
duke@1:
jjg@1410: protected final ClassTree classtree;
duke@1:
jjg@1410: protected final ClassDoc prev;
duke@1:
jjg@1410: protected final ClassDoc next;
duke@1:
duke@1: /**
jjg@1410: * @param configuration the configuration data for the doclet
duke@1: * @param classDoc the class being documented.
duke@1: * @param prevClass the previous class that was documented.
duke@1: * @param nextClass the next class being documented.
duke@1: * @param classTree the class tree for the given class.
duke@1: */
jjg@1410: public ClassWriterImpl (ConfigurationImpl configuration, ClassDoc classDoc,
duke@1: ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
jjg@1410: throws IOException {
jjg@1410: super(configuration, DocPath.forClass(classDoc));
duke@1: this.classDoc = classDoc;
duke@1: configuration.currentcd = classDoc;
duke@1: this.classtree = classTree;
duke@1: this.prev = prevClass;
duke@1: this.next = nextClass;
duke@1: }
duke@1:
duke@1: /**
bpatel@766: * Get this package link.
bpatel@766: *
bpatel@766: * @return a content tree for the package link
duke@1: */
bpatel@766: protected Content getNavLinkPackage() {
jjg@1373: Content linkContent = getHyperLink(DocPaths.PACKAGE_SUMMARY,
bpatel@766: packageLabel);
bpatel@766: Content li = HtmlTree.LI(linkContent);
bpatel@766: return li;
duke@1: }
duke@1:
duke@1: /**
bpatel@766: * Get the class link.
bpatel@766: *
bpatel@766: * @return a content tree for the class link
duke@1: */
bpatel@766: protected Content getNavLinkClass() {
bpatel@766: Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, classLabel);
bpatel@766: return li;
duke@1: }
duke@1:
duke@1: /**
bpatel@766: * Get the class use link.
bpatel@766: *
bpatel@766: * @return a content tree for the class use link
duke@1: */
bpatel@766: protected Content getNavLinkClassUse() {
jjg@1373: Content linkContent = getHyperLink(DocPaths.CLASS_USE.resolve(filename), useLabel);
bpatel@766: Content li = HtmlTree.LI(linkContent);
bpatel@766: return li;
duke@1: }
duke@1:
duke@1: /**
bpatel@766: * Get link to previous class.
bpatel@766: *
bpatel@766: * @return a content tree for the previous class link
duke@1: */
bpatel@766: public Content getNavLinkPrevious() {
bpatel@766: Content li;
bpatel@766: if (prev != null) {
jjg@1736: Content prevLink = getLink(new LinkInfoImpl(configuration,
jjg@1738: LinkInfoImpl.Kind.CLASS, prev)
jjg@1738: .label(configuration.getText("doclet.Prev_Class")).strong(true));
bpatel@766: li = HtmlTree.LI(prevLink);
duke@1: }
bpatel@766: else
bpatel@766: li = HtmlTree.LI(prevclassLabel);
bpatel@766: return li;
duke@1: }
duke@1:
duke@1: /**
bpatel@766: * Get link to next class.
bpatel@766: *
bpatel@766: * @return a content tree for the next class link
duke@1: */
bpatel@766: public Content getNavLinkNext() {
bpatel@766: Content li;
bpatel@766: if (next != null) {
jjg@1736: Content nextLink = getLink(new LinkInfoImpl(configuration,
jjg@1738: LinkInfoImpl.Kind.CLASS, next)
jjg@1738: .label(configuration.getText("doclet.Next_Class")).strong(true));
bpatel@766: li = HtmlTree.LI(nextLink);
duke@1: }
bpatel@766: else
bpatel@766: li = HtmlTree.LI(nextclassLabel);
bpatel@766: return li;
duke@1: }
duke@1:
duke@1: /**
duke@1: * {@inheritDoc}
duke@1: */
bpatel@766: public Content getHeader(String header) {
duke@1: String pkgname = (classDoc.containingPackage() != null)?
duke@1: classDoc.containingPackage().name(): "";
duke@1: String clname = classDoc.name();
bpatel@766: Content bodyTree = getBody(true, getWindowTitle(clname));
bpatel@766: addTop(bodyTree);
bpatel@766: addNavLinks(true, bodyTree);
bpatel@766: bodyTree.addContent(HtmlConstants.START_OF_CLASS_DATA);
bpatel@766: HtmlTree div = new HtmlTree(HtmlTag.DIV);
bpatel@766: div.addStyle(HtmlStyle.header);
bpatel@1568: if (configuration.showProfiles) {
bpatel@1568: String sep = "";
bpatel@1568: int profile = configuration.profiles.getProfile(getTypeNameForProfile(classDoc));
bpatel@1568: if (profile > 0) {
bpatel@1568: Content profNameContent = new StringContent();
bpatel@1568: for (int i = profile; i < configuration.profiles.getProfileCount(); i++) {
bpatel@1568: profNameContent.addContent(sep);
bpatel@1568: profNameContent.addContent(Profile.lookup(i).name);
bpatel@1568: sep = ", ";
bpatel@1568: }
bpatel@1568: Content profileNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, profNameContent);
bpatel@1568: div.addContent(profileNameDiv);
bpatel@1568: }
bpatel@1568: }
duke@1: if (pkgname.length() > 0) {
bpatel@766: Content pkgNameContent = new StringContent(pkgname);
bpatel@943: Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
bpatel@943: div.addContent(pkgNameDiv);
duke@1: }
jjg@1410: LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
jjg@1738: LinkInfoImpl.Kind.CLASS_HEADER, classDoc);
duke@1: //Let's not link to ourselves in the header.
duke@1: linkInfo.linkToSelf = false;
bpatel@766: Content headerContent = new StringContent(header);
bpatel@766: Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
bpatel@766: HtmlStyle.title, headerContent);
jjg@1736: heading.addContent(getTypeParameterLinks(linkInfo));
bpatel@766: div.addContent(heading);
bpatel@766: bodyTree.addContent(div);
bpatel@766: return bodyTree;
duke@1: }
duke@1:
duke@1: /**
duke@1: * {@inheritDoc}
duke@1: */
bpatel@766: public Content getClassContentHeader() {
bpatel@766: return getContentHeader();
duke@1: }
duke@1:
duke@1: /**
duke@1: * {@inheritDoc}
duke@1: */
bpatel@766: public void addFooter(Content contentTree) {
bpatel@766: contentTree.addContent(HtmlConstants.END_OF_CLASS_DATA);
bpatel@766: addNavLinks(false, contentTree);
bpatel@766: addBottom(contentTree);
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
jjg@1364: public void printDocument(Content contentTree) throws IOException {
bpatel@766: printHtmlDocument(configuration.metakeywords.getMetaKeywords(classDoc),
bpatel@766: true, contentTree);
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
bpatel@766: public Content getClassInfoTreeHeader() {
bpatel@766: return getMemberTreeHeader();
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
bpatel@766: public Content getClassInfo(Content classInfoTree) {
bpatel@766: return getMemberTree(HtmlStyle.description, classInfoTree);
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
bpatel@766: public void addClassSignature(String modifiers, Content classInfoTree) {
duke@1: boolean isInterface = classDoc.isInterface();
bpatel@766: classInfoTree.addContent(new HtmlTree(HtmlTag.BR));
bpatel@766: Content pre = new HtmlTree(HtmlTag.PRE);
bpatel@766: addAnnotationInfo(classDoc, pre);
bpatel@766: pre.addContent(modifiers);
jjg@1410: LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
jjg@1738: LinkInfoImpl.Kind.CLASS_SIGNATURE, classDoc);
duke@1: //Let's not link to ourselves in the signature.
duke@1: linkInfo.linkToSelf = false;
bpatel@958: Content className = new StringContent(classDoc.name());
jjg@1736: Content parameterLinks = getTypeParameterLinks(linkInfo);
jjg@1410: if (configuration.linksource) {
bpatel@958: addSrcLink(classDoc, className, pre);
bpatel@958: pre.addContent(parameterLinks);
duke@1: } else {
bpatel@958: Content span = HtmlTree.SPAN(HtmlStyle.strong, className);
bpatel@958: span.addContent(parameterLinks);
bpatel@958: pre.addContent(span);
duke@1: }
duke@1: if (!isInterface) {
duke@1: Type superclass = Util.getFirstVisibleSuperClass(classDoc,
jjg@1410: configuration);
duke@1: if (superclass != null) {
bpatel@793: pre.addContent(DocletConstants.NL);
bpatel@766: pre.addContent("extends ");
jjg@1736: Content link = getLink(new LinkInfoImpl(configuration,
jjg@1735: LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
jjg@1736: superclass));
bpatel@766: pre.addContent(link);
duke@1: }
duke@1: }
duke@1: Type[] implIntfacs = classDoc.interfaceTypes();
duke@1: if (implIntfacs != null && implIntfacs.length > 0) {
duke@1: int counter = 0;
duke@1: for (int i = 0; i < implIntfacs.length; i++) {
duke@1: ClassDoc classDoc = implIntfacs[i].asClassDoc();
duke@1: if (! (classDoc.isPublic() ||
jjg@1410: Util.isLinkable(classDoc, configuration))) {
duke@1: continue;
duke@1: }
duke@1: if (counter == 0) {
bpatel@793: pre.addContent(DocletConstants.NL);
bpatel@766: pre.addContent(isInterface? "extends " : "implements ");
duke@1: } else {
bpatel@766: pre.addContent(", ");
duke@1: }
jjg@1736: Content link = getLink(new LinkInfoImpl(configuration,
jjg@1735: LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME,
jjg@1736: implIntfacs[i]));
bpatel@766: pre.addContent(link);
duke@1: counter++;
duke@1: }
duke@1: }
bpatel@766: classInfoTree.addContent(pre);
duke@1: }
duke@1:
duke@1: /**
duke@1: * {@inheritDoc}
duke@1: */
bpatel@766: public void addClassDescription(Content classInfoTree) {
duke@1: if(!configuration.nocomment) {
duke@1: // generate documentation for the class.
duke@1: if (classDoc.inlineTags().length > 0) {
bpatel@766: addInlineComment(classDoc, classInfoTree);
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * {@inheritDoc}
duke@1: */
bpatel@766: public void addClassTagInfo(Content classInfoTree) {
duke@1: if(!configuration.nocomment) {
duke@1: // Print Information about all the tags here
bpatel@766: addTagsInfo(classDoc, classInfoTree);
bpatel@766: }
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * Get the class hierarchy tree for the given class.
bpatel@766: *
bpatel@766: * @param type the class to print the hierarchy for
bpatel@766: * @return a content tree for class inheritence
bpatel@766: */
bpatel@766: private Content getClassInheritenceTree(Type type) {
bpatel@766: Type sup;
bpatel@766: HtmlTree classTreeUl = new HtmlTree(HtmlTag.UL);
bpatel@766: classTreeUl.addStyle(HtmlStyle.inheritance);
bpatel@766: Content liTree = null;
bpatel@766: do {
bpatel@766: sup = Util.getFirstVisibleSuperClass(
bpatel@766: type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
jjg@1410: configuration);
bpatel@766: if (sup != null) {
bpatel@766: HtmlTree ul = new HtmlTree(HtmlTag.UL);
bpatel@766: ul.addStyle(HtmlStyle.inheritance);
bpatel@766: ul.addContent(getTreeForClassHelper(type));
bpatel@766: if (liTree != null)
bpatel@766: ul.addContent(liTree);
bpatel@766: Content li = HtmlTree.LI(ul);
bpatel@766: liTree = li;
bpatel@766: type = sup;
bpatel@766: }
bpatel@766: else
bpatel@766: classTreeUl.addContent(getTreeForClassHelper(type));
bpatel@766: }
bpatel@766: while (sup != null);
bpatel@766: if (liTree != null)
bpatel@766: classTreeUl.addContent(liTree);
bpatel@766: return classTreeUl;
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * Get the class helper tree for the given class.
bpatel@766: *
bpatel@766: * @param type the class to print the helper for
bpatel@766: * @return a content tree for class helper
bpatel@766: */
bpatel@766: private Content getTreeForClassHelper(Type type) {
bpatel@766: Content li = new HtmlTree(HtmlTag.LI);
bpatel@766: if (type.equals(classDoc)) {
jjg@1736: Content typeParameters = getTypeParameterLinks(
jjg@1735: new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE,
jjg@1738: classDoc));
bpatel@766: if (configuration.shouldExcludeQualifier(
bpatel@766: classDoc.containingPackage().name())) {
bpatel@766: li.addContent(type.asClassDoc().name());
jjg@1736: li.addContent(typeParameters);
bpatel@766: } else {
bpatel@766: li.addContent(type.asClassDoc().qualifiedName());
jjg@1736: li.addContent(typeParameters);
bpatel@766: }
duke@1: } else {
jjg@1736: Content link = getLink(new LinkInfoImpl(configuration,
jjg@1738: LinkInfoImpl.Kind.CLASS_TREE_PARENT, type)
jjg@1738: .label(configuration.getClassName(type.asClassDoc())));
bpatel@766: li.addContent(link);
bpatel@766: }
bpatel@766: return li;
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
bpatel@766: public void addClassTree(Content classContentTree) {
bpatel@766: if (!classDoc.isClass()) {
bpatel@766: return;
bpatel@766: }
bpatel@766: classContentTree.addContent(getClassInheritenceTree(classDoc));
bpatel@766: }
bpatel@766:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
bpatel@766: public void addTypeParamInfo(Content classInfoTree) {
bpatel@766: if (classDoc.typeParamTags().length > 0) {
bpatel@766: TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
bpatel@766: getTagletWriterInstance(false));
bpatel@766: Content typeParam = new RawHtml(output.toString());
bpatel@766: Content dl = HtmlTree.DL(typeParam);
bpatel@766: classInfoTree.addContent(dl);
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * {@inheritDoc}
duke@1: */
bpatel@766: public void addSubClassInfo(Content classInfoTree) {
duke@1: if (classDoc.isClass()) {
duke@1: if (classDoc.qualifiedName().equals("java.lang.Object") ||
bpatel@766: classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
duke@1: return; // Don't generate the list, too huge
duke@1: }
mcimadamore@184: List