Mon, 19 Nov 2012 16:10:34 -0800
8002304: Group methods by types in methods summary section
Reviewed-by: jjg
1 /*
2 * Copyright (c) 2003, 2012, 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 */
26 package com.sun.tools.doclets.internal.toolkit.builders;
28 import java.util.*;
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.*;
32 import com.sun.tools.doclets.internal.toolkit.util.*;
34 /**
35 * Builds the member summary.
36 *
37 * <p><b>This is NOT part of any supported API.
38 * If you write code that depends on this, you do so at your own risk.
39 * This code and its internal interfaces are subject to change or
40 * deletion without notice.</b>
41 *
42 * @author Jamie Ho
43 * @author Bhavesh Patel (Modified)
44 * @since 1.5
45 */
46 public class MemberSummaryBuilder extends AbstractMemberBuilder {
48 /**
49 * The XML root for this builder.
50 */
51 public static final String NAME = "MemberSummary";
53 /**
54 * The visible members for the given class.
55 */
56 private final VisibleMemberMap[] visibleMemberMaps;
58 /**
59 * The member summary writers for the given class.
60 */
61 private MemberSummaryWriter[] memberSummaryWriters;
63 /**
64 * The type being documented.
65 */
66 private final ClassDoc classDoc;
68 /**
69 * Construct a new MemberSummaryBuilder.
70 *
71 * @param classWriter the writer for the class whose members are being
72 * summarized.
73 * @param context the build context.
74 */
75 private MemberSummaryBuilder(Context context, ClassDoc classDoc) {
76 super(context);
77 this.classDoc = classDoc;
78 visibleMemberMaps =
79 new VisibleMemberMap[VisibleMemberMap.NUM_MEMBER_TYPES];
80 for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
81 visibleMemberMaps[i] =
82 new VisibleMemberMap(
83 classDoc,
84 i,
85 configuration.nodeprecated);
86 }
87 }
89 /**
90 * Construct a new MemberSummaryBuilder.
91 *
92 * @param classWriter the writer for the class whose members are being
93 * summarized.
94 * @param context the build context.
95 */
96 public static MemberSummaryBuilder getInstance(
97 ClassWriter classWriter, Context context)
98 throws Exception {
99 MemberSummaryBuilder builder = new MemberSummaryBuilder(context,
100 classWriter.getClassDoc());
101 builder.memberSummaryWriters =
102 new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
103 WriterFactory wf = context.configuration.getWriterFactory();
104 for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
105 builder.memberSummaryWriters[i] =
106 builder.visibleMemberMaps[i].noVisibleMembers() ?
107 null :
108 wf.getMemberSummaryWriter(classWriter, i);
109 }
110 return builder;
111 }
113 /**
114 * Construct a new MemberSummaryBuilder.
115 *
116 * @param annotationTypeWriter the writer for the class whose members are
117 * being summarized.
118 * @param configuration the current configuration of the doclet.
119 */
120 public static MemberSummaryBuilder getInstance(
121 AnnotationTypeWriter annotationTypeWriter, Context context)
122 throws Exception {
123 MemberSummaryBuilder builder = new MemberSummaryBuilder(context,
124 annotationTypeWriter.getAnnotationTypeDoc());
125 builder.memberSummaryWriters =
126 new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
127 WriterFactory wf = context.configuration.getWriterFactory();
128 for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
129 builder.memberSummaryWriters[i] =
130 builder.visibleMemberMaps[i].noVisibleMembers()?
131 null :
132 wf.getMemberSummaryWriter(
133 annotationTypeWriter, i);
134 }
135 return builder;
136 }
138 /**
139 * {@inheritDoc}
140 */
141 public String getName() {
142 return NAME;
143 }
145 /**
146 * Return the specified visible member map.
147 *
148 * @param type the type of visible member map to return.
149 * @return the specified visible member map.
150 * @throws ArrayIndexOutOfBoundsException when the type is invalid.
151 * @see VisibleMemberMap
152 */
153 public VisibleMemberMap getVisibleMemberMap(int type) {
154 return visibleMemberMaps[type];
155 }
157 /**
158 * Return the specified member summary writer.
159 *
160 * @param type the type of member summary writer to return.
161 * @return the specified member summary writer.
162 * @throws ArrayIndexOutOfBoundsException when the type is invalid.
163 * @see VisibleMemberMap
164 */
165 public MemberSummaryWriter getMemberSummaryWriter(int type) {
166 return memberSummaryWriters[type];
167 }
169 /**
170 * Returns a list of methods that will be documented for the given class.
171 * This information can be used for doclet specific documentation
172 * generation.
173 *
174 * @param type the type of members to return.
175 * @return a list of methods that will be documented.
176 * @see VisibleMemberMap
177 */
178 public List<ProgramElementDoc> members(int type) {
179 return visibleMemberMaps[type].getLeafClassMembers(configuration);
180 }
182 /**
183 * Return true it there are any members to summarize.
184 *
185 * @return true if there are any members to summarize.
186 */
187 public boolean hasMembersToDocument() {
188 if (classDoc instanceof AnnotationTypeDoc) {
189 return ((AnnotationTypeDoc) classDoc).elements().length > 0;
190 }
191 for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
192 VisibleMemberMap members = visibleMemberMaps[i];
193 if (!members.noVisibleMembers()) {
194 return true;
195 }
196 }
197 return false;
198 }
200 /**
201 * Build the summary for the enum constants.
202 *
203 * @param node the XML element that specifies which components to document
204 * @param memberSummaryTree the content tree to which the documentation will be added
205 */
206 public void buildEnumConstantsSummary(XMLNode node, Content memberSummaryTree) {
207 MemberSummaryWriter writer =
208 memberSummaryWriters[VisibleMemberMap.ENUM_CONSTANTS];
209 VisibleMemberMap visibleMemberMap =
210 visibleMemberMaps[VisibleMemberMap.ENUM_CONSTANTS];
211 addSummary(writer, visibleMemberMap, false, memberSummaryTree);
212 }
214 /**
215 * Build the summary for the optional members.
216 *
217 * @param node the XML element that specifies which components to document
218 * @param memberSummaryTree the content tree to which the documentation will be added
219 */
220 public void buildAnnotationTypeOptionalMemberSummary(XMLNode node, Content memberSummaryTree) {
221 MemberSummaryWriter writer =
222 memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL];
223 VisibleMemberMap visibleMemberMap =
224 visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL];
225 addSummary(writer, visibleMemberMap, false, memberSummaryTree);
226 }
228 /**
229 * Build the summary for the optional members.
230 *
231 * @param node the XML element that specifies which components to document
232 * @param memberSummaryTree the content tree to which the documentation will be added
233 */
234 public void buildAnnotationTypeRequiredMemberSummary(XMLNode node, Content memberSummaryTree) {
235 MemberSummaryWriter writer =
236 memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED];
237 VisibleMemberMap visibleMemberMap =
238 visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED];
239 addSummary(writer, visibleMemberMap, false, memberSummaryTree);
240 }
242 /**
243 * Build the summary for the fields.
244 *
245 * @param node the XML element that specifies which components to document
246 * @param memberSummaryTree the content tree to which the documentation will be added
247 */
248 public void buildFieldsSummary(XMLNode node, Content memberSummaryTree) {
249 MemberSummaryWriter writer =
250 memberSummaryWriters[VisibleMemberMap.FIELDS];
251 VisibleMemberMap visibleMemberMap =
252 visibleMemberMaps[VisibleMemberMap.FIELDS];
253 addSummary(writer, visibleMemberMap, true, memberSummaryTree);
254 }
256 /**
257 * Build the summary for the nested classes.
258 *
259 * @param node the XML element that specifies which components to document
260 * @param memberSummaryTree the content tree to which the documentation will be added
261 */
262 public void buildNestedClassesSummary(XMLNode node, Content memberSummaryTree) {
263 MemberSummaryWriter writer =
264 memberSummaryWriters[VisibleMemberMap.INNERCLASSES];
265 VisibleMemberMap visibleMemberMap =
266 visibleMemberMaps[VisibleMemberMap.INNERCLASSES];
267 addSummary(writer, visibleMemberMap, true, memberSummaryTree);
268 }
270 /**
271 * Build the method summary.
272 *
273 * @param node the XML element that specifies which components to document
274 * @param memberSummaryTree the content tree to which the documentation will be added
275 */
276 public void buildMethodsSummary(XMLNode node, Content memberSummaryTree) {
277 MemberSummaryWriter writer =
278 memberSummaryWriters[VisibleMemberMap.METHODS];
279 VisibleMemberMap visibleMemberMap =
280 visibleMemberMaps[VisibleMemberMap.METHODS];
281 addSummary(writer, visibleMemberMap, true, memberSummaryTree);
282 }
284 /**
285 * Build the constructor summary.
286 *
287 * @param node the XML element that specifies which components to document
288 * @param memberSummaryTree the content tree to which the documentation will be added
289 */
290 public void buildConstructorsSummary(XMLNode node, Content memberSummaryTree) {
291 MemberSummaryWriter writer =
292 memberSummaryWriters[VisibleMemberMap.CONSTRUCTORS];
293 VisibleMemberMap visibleMemberMap =
294 visibleMemberMaps[VisibleMemberMap.CONSTRUCTORS];
295 addSummary(writer, visibleMemberMap, false, memberSummaryTree);
296 }
298 /**
299 * Build the member summary for the given members.
300 *
301 * @param writer the summary writer to write the output.
302 * @param visibleMemberMap the given members to summarize.
303 * @param summaryTreeList list of content trees to which the documentation will be added
304 */
305 private void buildSummary(MemberSummaryWriter writer,
306 VisibleMemberMap visibleMemberMap, LinkedList<Content> summaryTreeList) {
307 List<ProgramElementDoc> members = new ArrayList<ProgramElementDoc>(visibleMemberMap.getLeafClassMembers(
308 configuration));
309 if (members.size() > 0) {
310 Collections.sort(members);
311 List<Content> tableContents = new LinkedList<Content>();
312 for (int i = 0; i < members.size(); i++) {
313 ProgramElementDoc member = members.get(i);
314 Tag[] firstSentenceTags = member.firstSentenceTags();
315 if (member instanceof MethodDoc && firstSentenceTags.length == 0) {
316 //Inherit comments from overriden or implemented method if
317 //necessary.
318 DocFinder.Output inheritedDoc =
319 DocFinder.search(new DocFinder.Input((MethodDoc) member));
320 if (inheritedDoc.holder != null
321 && inheritedDoc.holder.firstSentenceTags().length > 0) {
322 firstSentenceTags = inheritedDoc.holder.firstSentenceTags();
323 }
324 }
325 writer.addMemberSummary(classDoc, member, firstSentenceTags,
326 tableContents, i);
327 }
328 summaryTreeList.add(writer.getSummaryTableTree(classDoc, tableContents));
329 }
330 }
332 /**
333 * Build the inherited member summary for the given methods.
334 *
335 * @param writer the writer for this member summary.
336 * @param visibleMemberMap the map for the members to document.
337 * @param summaryTreeList list of content trees to which the documentation will be added
338 */
339 private void buildInheritedSummary(MemberSummaryWriter writer,
340 VisibleMemberMap visibleMemberMap, LinkedList<Content> summaryTreeList) {
341 for (Iterator<ClassDoc> iter = visibleMemberMap.getVisibleClassesList().iterator();
342 iter.hasNext();) {
343 ClassDoc inhclass = iter.next();
344 if (! (inhclass.isPublic() ||
345 Util.isLinkable(inhclass, configuration))) {
346 continue;
347 }
348 if (inhclass == classDoc) {
349 continue;
350 }
351 List<ProgramElementDoc> inhmembers = visibleMemberMap.getMembersFor(inhclass);
352 if (inhmembers.size() > 0) {
353 Collections.sort(inhmembers);
354 Content inheritedTree = writer.getInheritedSummaryHeader(inhclass);
355 Content linksTree = writer.getInheritedSummaryLinksTree();
356 for (int j = 0; j < inhmembers.size(); ++j) {
357 writer.addInheritedMemberSummary(
358 inhclass.isPackagePrivate() &&
359 ! Util.isLinkable(inhclass, configuration) ?
360 classDoc : inhclass,
361 inhmembers.get(j),
362 j == 0,
363 j == inhmembers.size() - 1, linksTree);
364 }
365 inheritedTree.addContent(linksTree);
366 summaryTreeList.add(writer.getMemberTree(inheritedTree));
367 }
368 }
369 }
371 /**
372 * Add the summary for the documentation.
373 *
374 * @param writer the writer for this member summary.
375 * @param visibleMemberMap the map for the members to document.
376 * @param showInheritedSummary true if inherited summary should be documented
377 * @param memberSummaryTree the content tree to which the documentation will be added
378 */
379 private void addSummary(MemberSummaryWriter writer,
380 VisibleMemberMap visibleMemberMap, boolean showInheritedSummary,
381 Content memberSummaryTree) {
382 LinkedList<Content> summaryTreeList = new LinkedList<Content>();
383 buildSummary(writer, visibleMemberMap, summaryTreeList);
384 if (showInheritedSummary)
385 buildInheritedSummary(writer, visibleMemberMap, summaryTreeList);
386 if (!summaryTreeList.isEmpty()) {
387 Content memberTree = writer.getMemberSummaryHeader(
388 classDoc, memberSummaryTree);
389 for (int i = 0; i < summaryTreeList.size(); i++) {
390 memberTree.addContent(summaryTreeList.get(i));
391 }
392 memberSummaryTree.addContent(writer.getMemberTree(memberTree));
393 }
394 }
395 }