duke@1: /*
jjg@1357: * Copyright (c) 2003, 2012, 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.internal.toolkit.builders;
duke@1:
bpatel@766: import java.util.*;
jjg@1357:
jjg@1357: import com.sun.javadoc.*;
jjg@1357: import com.sun.tools.doclets.internal.toolkit.*;
duke@1: import com.sun.tools.doclets.internal.toolkit.util.*;
duke@1:
duke@1: /**
duke@1: * Builds the member summary.
duke@1: *
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.
duke@1: *
duke@1: * @author Jamie Ho
bpatel@766: * @author Bhavesh Patel (Modified)
duke@1: * @since 1.5
duke@1: */
duke@1: public class MemberSummaryBuilder extends AbstractMemberBuilder {
duke@1:
bpatel@766: /**
bpatel@766: * The XML root for this builder.
bpatel@766: */
bpatel@766: public static final String NAME = "MemberSummary";
duke@1:
bpatel@766: /**
bpatel@766: * The visible members for the given class.
bpatel@766: */
bpatel@766: private VisibleMemberMap[] visibleMemberMaps;
duke@1:
bpatel@766: /**
bpatel@766: * The member summary writers for the given class.
bpatel@766: */
bpatel@766: private MemberSummaryWriter[] memberSummaryWriters;
duke@1:
bpatel@766: /**
bpatel@766: * The type being documented.
bpatel@766: */
bpatel@766: private ClassDoc classDoc;
duke@1:
bpatel@766: private MemberSummaryBuilder(Configuration configuration) {
bpatel@766: super(configuration);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Construct a new MemberSummaryBuilder.
bpatel@766: *
bpatel@766: * @param classWriter the writer for the class whose members are being
bpatel@766: * summarized.
bpatel@766: * @param configuration the current configuration of the doclet.
bpatel@766: */
bpatel@766: public static MemberSummaryBuilder getInstance(
bpatel@766: ClassWriter classWriter, Configuration configuration)
bpatel@766: throws Exception {
bpatel@766: MemberSummaryBuilder builder = new MemberSummaryBuilder(configuration);
bpatel@766: builder.classDoc = classWriter.getClassDoc();
bpatel@766: builder.init(classWriter);
bpatel@766: return builder;
bpatel@766: }
duke@1:
duke@1: /**
duke@1: * Construct a new MemberSummaryBuilder.
duke@1: *
duke@1: * @param annotationTypeWriter the writer for the class whose members are
duke@1: * being summarized.
duke@1: * @param configuration the current configuration of the doclet.
duke@1: */
duke@1: public static MemberSummaryBuilder getInstance(
bpatel@766: AnnotationTypeWriter annotationTypeWriter, Configuration configuration)
bpatel@766: throws Exception {
duke@1: MemberSummaryBuilder builder = new MemberSummaryBuilder(configuration);
duke@1: builder.classDoc = annotationTypeWriter.getAnnotationTypeDoc();
duke@1: builder.init(annotationTypeWriter);
duke@1: return builder;
duke@1: }
duke@1:
duke@1: private void init(Object writer) throws Exception {
duke@1: visibleMemberMaps =
bpatel@766: new VisibleMemberMap[VisibleMemberMap.NUM_MEMBER_TYPES];
duke@1: for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
duke@1: visibleMemberMaps[i] =
bpatel@766: new VisibleMemberMap(
duke@1: classDoc,
duke@1: i,
duke@1: configuration.nodeprecated);
duke@1: }
duke@1: memberSummaryWriters =
bpatel@766: new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
duke@1: for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
duke@1: if (classDoc.isAnnotationType()) {
duke@1: memberSummaryWriters[i] =
duke@1: visibleMemberMaps[i].noVisibleMembers()?
duke@1: null :
duke@1: configuration.getWriterFactory().getMemberSummaryWriter(
bpatel@766: (AnnotationTypeWriter) writer, i);
duke@1: } else {
duke@1: memberSummaryWriters[i] =
duke@1: visibleMemberMaps[i].noVisibleMembers()?
duke@1: null :
duke@1: configuration.getWriterFactory().getMemberSummaryWriter(
bpatel@766: (ClassWriter) writer, i);
duke@1: }
duke@1: }
duke@1:
duke@1: }
duke@1:
bpatel@766: /**
bpatel@766: * {@inheritDoc}
bpatel@766: */
bpatel@766: public String getName() {
bpatel@766: return NAME;
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Return the specified visible member map.
bpatel@766: *
bpatel@766: * @param type the type of visible member map to return.
bpatel@766: * @return the specified visible member map.
bpatel@766: * @throws ArrayIndexOutOfBoundsException when the type is invalid.
bpatel@766: * @see VisibleMemberMap
bpatel@766: */
bpatel@766: public VisibleMemberMap getVisibleMemberMap(int type) {
bpatel@766: return visibleMemberMaps[type];
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Return the specified member summary writer.
bpatel@766: *
bpatel@766: * @param type the type of member summary writer to return.
bpatel@766: * @return the specified member summary writer.
bpatel@766: * @throws ArrayIndexOutOfBoundsException when the type is invalid.
bpatel@766: * @see VisibleMemberMap
bpatel@766: */
bpatel@766: public MemberSummaryWriter getMemberSummaryWriter(int type) {
bpatel@766: return memberSummaryWriters[type];
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Returns a list of methods that will be documented for the given class.
bpatel@766: * This information can be used for doclet specific documentation
bpatel@766: * generation.
bpatel@766: *
bpatel@766: * @param type the type of members to return.
bpatel@766: * @return a list of methods that will be documented.
bpatel@766: * @see VisibleMemberMap
bpatel@766: */
bpatel@766: public List members(int type) {
bpatel@766: return visibleMemberMaps[type].getLeafClassMembers(configuration);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Return true it there are any members to summarize.
bpatel@766: *
bpatel@766: * @return true if there are any members to summarize.
bpatel@766: */
bpatel@766: public boolean hasMembersToDocument() {
duke@1: if (classDoc instanceof AnnotationTypeDoc) {
duke@1: return ((AnnotationTypeDoc) classDoc).elements().length > 0;
duke@1: }
bpatel@766: for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
bpatel@766: VisibleMemberMap members = visibleMemberMaps[i];
bpatel@766: if (!members.noVisibleMembers()) {
bpatel@766: return true;
bpatel@766: }
duke@1: }
bpatel@766: return false;
bpatel@766: }
duke@1:
duke@1: /**
bpatel@766: * Build the summary for the enum constants.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
duke@1: */
bpatel@766: public void buildEnumConstantsSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.ENUM_CONSTANTS];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.ENUM_CONSTANTS];
bpatel@766: addSummary(writer, visibleMemberMap, false, memberSummaryTree);
duke@1: }
duke@1:
duke@1: /**
duke@1: * Build the summary for the optional members.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
duke@1: */
bpatel@766: public void buildAnnotationTypeOptionalMemberSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL];
bpatel@766: addSummary(writer, visibleMemberMap, false, memberSummaryTree);
duke@1: }
duke@1:
bpatel@766: /**
bpatel@766: * Build the summary for the optional members.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
bpatel@766: */
bpatel@766: public void buildAnnotationTypeRequiredMemberSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED];
bpatel@766: addSummary(writer, visibleMemberMap, false, memberSummaryTree);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Build the summary for the fields.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
bpatel@766: */
bpatel@766: public void buildFieldsSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.FIELDS];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.FIELDS];
bpatel@766: addSummary(writer, visibleMemberMap, true, memberSummaryTree);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Build the summary for the nested classes.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
bpatel@766: */
bpatel@766: public void buildNestedClassesSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.INNERCLASSES];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.INNERCLASSES];
bpatel@766: addSummary(writer, visibleMemberMap, true, memberSummaryTree);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Build the method summary.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
bpatel@766: */
bpatel@766: public void buildMethodsSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.METHODS];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.METHODS];
bpatel@766: addSummary(writer, visibleMemberMap, true, memberSummaryTree);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Build the constructor summary.
bpatel@766: *
bpatel@766: * @param node the XML element that specifies which components to document
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
bpatel@766: */
bpatel@766: public void buildConstructorsSummary(XMLNode node, Content memberSummaryTree) {
bpatel@766: MemberSummaryWriter writer =
bpatel@766: memberSummaryWriters[VisibleMemberMap.CONSTRUCTORS];
bpatel@766: VisibleMemberMap visibleMemberMap =
bpatel@766: visibleMemberMaps[VisibleMemberMap.CONSTRUCTORS];
bpatel@766: addSummary(writer, visibleMemberMap, false, memberSummaryTree);
bpatel@766: }
duke@1:
bpatel@766: /**
bpatel@766: * Build the member summary for the given members.
bpatel@766: *
bpatel@766: * @param writer the summary writer to write the output.
bpatel@766: * @param visibleMemberMap the given members to summarize.
bpatel@766: * @param summaryTreeList list of content trees to which the documentation will be added
bpatel@766: */
bpatel@766: private void buildSummary(MemberSummaryWriter writer,
bpatel@766: VisibleMemberMap visibleMemberMap, LinkedList summaryTreeList) {
jjg@74: List members = new ArrayList(visibleMemberMap.getLeafClassMembers(
bpatel@766: configuration));
duke@1: if (members.size() > 0) {
duke@1: Collections.sort(members);
bpatel@766: Content tableTree = writer.getSummaryTableTree(classDoc);
duke@1: for (int i = 0; i < members.size(); i++) {
jjg@74: ProgramElementDoc member = members.get(i);
duke@1: Tag[] firstSentenceTags = member.firstSentenceTags();
duke@1: if (member instanceof MethodDoc && firstSentenceTags.length == 0) {
duke@1: //Inherit comments from overriden or implemented method if
duke@1: //necessary.
duke@1: DocFinder.Output inheritedDoc =
bpatel@766: DocFinder.search(new DocFinder.Input((MethodDoc) member));
duke@1: if (inheritedDoc.holder != null &&
duke@1: inheritedDoc.holder.firstSentenceTags().length > 0) {
duke@1: firstSentenceTags = inheritedDoc.holder.firstSentenceTags();
duke@1: }
duke@1: }
bpatel@766: writer.addMemberSummary(classDoc, member, firstSentenceTags, tableTree, i);
duke@1: }
bpatel@766: summaryTreeList.add(tableTree);
duke@1: }
bpatel@766: }
duke@1:
duke@1: /**
duke@1: * Build the inherited member summary for the given methods.
duke@1: *
bpatel@766: * @param writer the writer for this member summary.
duke@1: * @param visibleMemberMap the map for the members to document.
bpatel@766: * @param summaryTreeList list of content trees to which the documentation will be added
duke@1: */
bpatel@766: private void buildInheritedSummary(MemberSummaryWriter writer,
bpatel@766: VisibleMemberMap visibleMemberMap, LinkedList summaryTreeList) {
mcimadamore@184: for (Iterator iter = visibleMemberMap.getVisibleClassesList().iterator();
duke@1: iter.hasNext();) {
mcimadamore@184: ClassDoc inhclass = iter.next();
duke@1: if (! (inhclass.isPublic() ||
bpatel@766: Util.isLinkable(inhclass, configuration))) {
duke@1: continue;
duke@1: }
duke@1: if (inhclass == classDoc) {
duke@1: continue;
duke@1: }
jjg@74: List inhmembers = visibleMemberMap.getMembersFor(inhclass);
duke@1: if (inhmembers.size() > 0) {
duke@1: Collections.sort(inhmembers);
bpatel@766: Content inheritedTree = writer.getInheritedSummaryHeader(inhclass);
bpatel@766: Content linksTree = writer.getInheritedSummaryLinksTree();
duke@1: for (int j = 0; j < inhmembers.size(); ++j) {
bpatel@766: writer.addInheritedMemberSummary(
bpatel@766: inhclass.isPackagePrivate() &&
duke@1: ! Util.isLinkable(inhclass, configuration) ?
duke@1: classDoc : inhclass,
bpatel@766: inhmembers.get(j),
bpatel@766: j == 0,
bpatel@766: j == inhmembers.size() - 1, linksTree);
duke@1: }
bpatel@766: inheritedTree.addContent(linksTree);
bpatel@766: summaryTreeList.add(writer.getMemberTree(inheritedTree));
duke@1: }
duke@1: }
duke@1: }
bpatel@766:
bpatel@766: /**
bpatel@766: * Add the summary for the documentation.
bpatel@766: *
bpatel@766: * @param writer the writer for this member summary.
bpatel@766: * @param visibleMemberMap the map for the members to document.
bpatel@766: * @param showInheritedSummary true if inherited summary should be documented
bpatel@766: * @param memberSummaryTree the content tree to which the documentation will be added
bpatel@766: */
bpatel@766: private void addSummary(MemberSummaryWriter writer,
bpatel@766: VisibleMemberMap visibleMemberMap, boolean showInheritedSummary,
bpatel@766: Content memberSummaryTree) {
bpatel@766: LinkedList summaryTreeList = new LinkedList();
bpatel@766: buildSummary(writer, visibleMemberMap, summaryTreeList);
bpatel@766: if (showInheritedSummary)
bpatel@766: buildInheritedSummary(writer, visibleMemberMap, summaryTreeList);
bpatel@766: if (!summaryTreeList.isEmpty()) {
bpatel@766: Content memberTree = writer.getMemberSummaryHeader(
bpatel@766: classDoc, memberSummaryTree);
bpatel@766: for (int i = 0; i < summaryTreeList.size(); i++) {
bpatel@766: memberTree.addContent(summaryTreeList.get(i));
bpatel@766: }
bpatel@766: memberSummaryTree.addContent(writer.getMemberTree(memberTree));
bpatel@766: }
bpatel@766: }
duke@1: }