001: /*
002: * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.doclets.internal.toolkit.builders;
027:
028: import com.sun.tools.doclets.internal.toolkit.util.*;
029: import com.sun.tools.doclets.internal.toolkit.*;
030: import com.sun.javadoc.*;
031: import java.util.*;
032: import java.lang.reflect.*;
033:
034: /**
035: * Builds the member summary.
036: *
037: * This code is not part of an API.
038: * It is implementation that is subject to change.
039: * Do not use it as an API
040: *
041: * @author Jamie Ho
042: * @since 1.5
043: */
044: public class MemberSummaryBuilder extends AbstractMemberBuilder {
045:
046: /**
047: * The XML root for this builder.
048: */
049: public static final String NAME = "MemberSummary";
050:
051: /**
052: * The visible members for the given class.
053: */
054: private VisibleMemberMap[] visibleMemberMaps;
055:
056: /**
057: * The member summary writers for the given class.
058: */
059: private MemberSummaryWriter[] memberSummaryWriters;
060:
061: /**
062: * The type being documented.
063: */
064: private ClassDoc classDoc;
065:
066: private MemberSummaryBuilder(Configuration configuration) {
067: super (configuration);
068: }
069:
070: /**
071: * Construct a new MemberSummaryBuilder.
072: *
073: * @param classWriter the writer for the class whose members are being
074: * summarized.
075: * @param configuration the current configuration of the doclet.
076: */
077: public static MemberSummaryBuilder getInstance(
078: ClassWriter classWriter, Configuration configuration)
079: throws Exception {
080: MemberSummaryBuilder builder = new MemberSummaryBuilder(
081: configuration);
082: builder.classDoc = classWriter.getClassDoc();
083: builder.init(classWriter);
084: return builder;
085: }
086:
087: /**
088: * Construct a new MemberSummaryBuilder.
089: *
090: * @param annotationTypeWriter the writer for the class whose members are
091: * being summarized.
092: * @param configuration the current configuration of the doclet.
093: */
094: public static MemberSummaryBuilder getInstance(
095: AnnotationTypeWriter annotationTypeWriter,
096: Configuration configuration) throws Exception {
097: MemberSummaryBuilder builder = new MemberSummaryBuilder(
098: configuration);
099: builder.classDoc = annotationTypeWriter.getAnnotationTypeDoc();
100: builder.init(annotationTypeWriter);
101: return builder;
102: }
103:
104: private void init(Object writer) throws Exception {
105: visibleMemberMaps = new VisibleMemberMap[VisibleMemberMap.NUM_MEMBER_TYPES];
106: for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
107: visibleMemberMaps[i] = new VisibleMemberMap(classDoc, i,
108: configuration.nodeprecated);
109: }
110: memberSummaryWriters = new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
111: for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
112: if (classDoc.isAnnotationType()) {
113: memberSummaryWriters[i] = visibleMemberMaps[i]
114: .noVisibleMembers() ? null : configuration
115: .getWriterFactory().getMemberSummaryWriter(
116: (AnnotationTypeWriter) writer, i);
117: } else {
118: memberSummaryWriters[i] = visibleMemberMaps[i]
119: .noVisibleMembers() ? null : configuration
120: .getWriterFactory().getMemberSummaryWriter(
121: (ClassWriter) writer, i);
122: }
123: }
124:
125: }
126:
127: /**
128: * {@inheritDoc}
129: */
130: public String getName() {
131: return NAME;
132: }
133:
134: /**
135: * Return the specified visible member map.
136: *
137: * @param type the type of visible member map to return.
138: * @return the specified visible member map.
139: * @throws ArrayIndexOutOfBoundsException when the type is invalid.
140: * @see VisibleMemberMap
141: */
142: public VisibleMemberMap getVisibleMemberMap(int type) {
143: return visibleMemberMaps[type];
144: }
145:
146: /**
147: * Return the specified member summary writer.
148: *
149: * @param type the type of member summary writer to return.
150: * @return the specified member summary writer.
151: * @throws ArrayIndexOutOfBoundsException when the type is invalid.
152: * @see VisibleMemberMap
153: */
154: public MemberSummaryWriter getMemberSummaryWriter(int type) {
155: return memberSummaryWriters[type];
156: }
157:
158: /**
159: * Returns a list of methods that will be documented for the given class.
160: * This information can be used for doclet specific documentation
161: * generation.
162: *
163: * @param classDoc the {@link ClassDoc} we want to check.
164: * @param type the type of members to return.
165: * @return a list of methods that will be documented.
166: * @see VisibleMemberMap
167: */
168: public List members(int type) {
169: return visibleMemberMaps[type]
170: .getLeafClassMembers(configuration);
171: }
172:
173: /**
174: * {@inheritDoc}
175: */
176: public void invokeMethod(String methodName, Class[] paramClasses,
177: Object[] params) throws Exception {
178: if (DEBUG) {
179: configuration.root.printError("DEBUG: "
180: + this .getClass().getName() + "." + methodName);
181: }
182: Method method = this .getClass().getMethod(methodName,
183: paramClasses);
184: method.invoke(this , params);
185: }
186:
187: /**
188: * Return true it there are any members to summarize.
189: *
190: * @return true if there are any members to summarize.
191: */
192: public boolean hasMembersToDocument() {
193: if (classDoc instanceof AnnotationTypeDoc) {
194: return ((AnnotationTypeDoc) classDoc).elements().length > 0;
195: }
196: for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
197: VisibleMemberMap members = visibleMemberMaps[i];
198: if (!members.noVisibleMembers()) {
199: return true;
200: }
201: }
202: return false;
203: }
204:
205: /**
206: * Build the summary for the enum constants.
207: */
208: public void buildEnumConstantsSummary() {
209: buildSummary(
210: memberSummaryWriters[VisibleMemberMap.ENUM_CONSTANTS],
211: visibleMemberMaps[VisibleMemberMap.ENUM_CONSTANTS]);
212: }
213:
214: /**
215: * Build the summary for the optional members.
216: */
217: public void buildAnnotationTypeOptionalMemberSummary() {
218: buildSummary(
219: memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL],
220: visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL]);
221: }
222:
223: /**
224: * Build the summary for the optional members.
225: */
226: public void buildAnnotationTypeRequiredMemberSummary() {
227: buildSummary(
228: memberSummaryWriters[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED],
229: visibleMemberMaps[VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED]);
230: }
231:
232: /**
233: * Build the summary for the fields.
234: */
235: public void buildFieldsSummary() {
236: buildSummary(memberSummaryWriters[VisibleMemberMap.FIELDS],
237: visibleMemberMaps[VisibleMemberMap.FIELDS]);
238: }
239:
240: /**
241: * Build the inherited summary for the fields.
242: */
243: public void buildFieldsInheritedSummary() {
244: buildInheritedSummary(
245: memberSummaryWriters[VisibleMemberMap.FIELDS],
246: visibleMemberMaps[VisibleMemberMap.FIELDS]);
247: }
248:
249: /**
250: * Build the summary for the nested classes.
251: */
252: public void buildNestedClassesSummary() {
253: buildSummary(
254: memberSummaryWriters[VisibleMemberMap.INNERCLASSES],
255: visibleMemberMaps[VisibleMemberMap.INNERCLASSES]);
256: }
257:
258: /**
259: * Build the inherited summary for the nested classes.
260: */
261: public void buildNestedClassesInheritedSummary() {
262: buildInheritedSummary(
263: memberSummaryWriters[VisibleMemberMap.INNERCLASSES],
264: visibleMemberMaps[VisibleMemberMap.INNERCLASSES]);
265: }
266:
267: /**
268: * Build the method summary.
269: */
270: public void buildMethodsSummary() {
271: buildSummary(memberSummaryWriters[VisibleMemberMap.METHODS],
272: visibleMemberMaps[VisibleMemberMap.METHODS]);
273: }
274:
275: /**
276: * Build the inherited method summary.
277: */
278: public void buildMethodsInheritedSummary() {
279: buildInheritedSummary(
280: memberSummaryWriters[VisibleMemberMap.METHODS],
281: visibleMemberMaps[VisibleMemberMap.METHODS]);
282: }
283:
284: /**
285: * Build the constructor summary.
286: */
287: public void buildConstructorsSummary() {
288: buildSummary(
289: memberSummaryWriters[VisibleMemberMap.CONSTRUCTORS],
290: visibleMemberMaps[VisibleMemberMap.CONSTRUCTORS]);
291: }
292:
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: */
299: private void buildSummary(MemberSummaryWriter writer,
300: VisibleMemberMap visibleMemberMap) {
301: List members = new ArrayList(visibleMemberMap
302: .getLeafClassMembers(configuration));
303: if (members.size() > 0) {
304: Collections.sort(members);
305: writer.writeMemberSummaryHeader(classDoc);
306: for (int i = 0; i < members.size(); i++) {
307: ProgramElementDoc member = (ProgramElementDoc) members
308: .get(i);
309: Tag[] firstSentenceTags = member.firstSentenceTags();
310: if (member instanceof MethodDoc
311: && firstSentenceTags.length == 0) {
312: //Inherit comments from overriden or implemented method if
313: //necessary.
314: DocFinder.Output inheritedDoc = DocFinder
315: .search(new DocFinder.Input(
316: (MethodDoc) member));
317: if (inheritedDoc.holder != null
318: && inheritedDoc.holder.firstSentenceTags().length > 0) {
319: firstSentenceTags = inheritedDoc.holder
320: .firstSentenceTags();
321: }
322: }
323: writer.writeMemberSummary(classDoc, member,
324: firstSentenceTags, i == 0,
325: i == members.size() - 1);
326: }
327: writer.writeMemberSummaryFooter(classDoc);
328: }
329: }
330:
331: /**
332: * Build the inherited member summary for the given methods.
333: *
334: * @param writer the writer for this member summary.
335: * @param visibleMemberMap the map for the members to document.
336: */
337: private void buildInheritedSummary(MemberSummaryWriter writer,
338: VisibleMemberMap visibleMemberMap) {
339: for (Iterator iter = visibleMemberMap.getVisibleClassesList()
340: .iterator(); iter.hasNext();) {
341: ClassDoc inhclass = (ClassDoc) (iter.next());
342: if (!(inhclass.isPublic() || Util.isLinkable(inhclass,
343: configuration))) {
344: continue;
345: }
346: if (inhclass == classDoc) {
347: continue;
348: }
349: List inhmembers = visibleMemberMap.getMembersFor(inhclass);
350: if (inhmembers.size() > 0) {
351: Collections.sort(inhmembers);
352: writer.writeInheritedMemberSummaryHeader(inhclass);
353: for (int j = 0; j < inhmembers.size(); ++j) {
354: writer.writeInheritedMemberSummary(
355: inhclass.isPackagePrivate()
356: && !Util.isLinkable(inhclass,
357: configuration) ? classDoc
358: : inhclass,
359: (ProgramElementDoc) inhmembers.get(j),
360: j == 0, j == inhmembers.size() - 1);
361: }
362: writer.writeInheritedMemberSummaryFooter(inhclass);
363: }
364: }
365: }
366: }
|