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