001: /*
002: * Copyright 1997-2006 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.formats.html;
027:
028: import com.sun.tools.doclets.internal.toolkit.util.*;
029: import com.sun.tools.doclets.internal.toolkit.taglets.*;
030:
031: import com.sun.javadoc.*;
032: import java.util.*;
033: import java.lang.reflect.Modifier;
034:
035: /**
036: * The base class for member writers.
037: *
038: * @author Robert Field
039: * @author Atul M Dambalkar
040: * @author Jamie Ho (Re-write)
041: */
042: public abstract class AbstractMemberWriter {
043:
044: protected boolean printedSummaryHeader = false;
045: protected final SubWriterHolderWriter writer;
046: protected final ClassDoc classdoc;
047: public final boolean nodepr;
048:
049: public AbstractMemberWriter(SubWriterHolderWriter writer,
050: ClassDoc classdoc) {
051: this .writer = writer;
052: this .nodepr = configuration().nodeprecated;
053: this .classdoc = classdoc;
054: }
055:
056: public AbstractMemberWriter(SubWriterHolderWriter writer) {
057: this (writer, null);
058: }
059:
060: /*** abstracts ***/
061:
062: public abstract void printSummaryLabel(ClassDoc cd);
063:
064: public abstract void printInheritedSummaryLabel(ClassDoc cd);
065:
066: public abstract void printSummaryAnchor(ClassDoc cd);
067:
068: public abstract void printInheritedSummaryAnchor(ClassDoc cd);
069:
070: protected abstract void printSummaryType(ProgramElementDoc member);
071:
072: protected void writeSummaryLink(ClassDoc cd,
073: ProgramElementDoc member) {
074: writeSummaryLink(LinkInfoImpl.CONTEXT_MEMBER, cd, member);
075: }
076:
077: protected abstract void writeSummaryLink(int context, ClassDoc cd,
078: ProgramElementDoc member);
079:
080: protected abstract void writeInheritedSummaryLink(ClassDoc cd,
081: ProgramElementDoc member);
082:
083: protected abstract void writeDeprecatedLink(ProgramElementDoc member);
084:
085: protected abstract void printNavSummaryLink(ClassDoc cd,
086: boolean link);
087:
088: protected abstract void printNavDetailLink(boolean link);
089:
090: /*** ***/
091:
092: protected void print(String str) {
093: writer.print(str);
094: writer.displayLength += str.length();
095: }
096:
097: protected void print(char ch) {
098: writer.print(ch);
099: writer.displayLength++;
100: }
101:
102: protected void bold(String str) {
103: writer.bold(str);
104: writer.displayLength += str.length();
105: }
106:
107: /**
108: * Return a string describing the access modifier flags.
109: * Don't include native or synchronized.
110: *
111: * The modifier names are returned in canonical order, as
112: * specified by <em>The Java Language Specification</em>.
113: */
114: protected String modifierString(MemberDoc member) {
115: int ms = member.modifierSpecifier();
116: int no = Modifier.NATIVE | Modifier.SYNCHRONIZED;
117: return Modifier.toString(ms & ~no);
118: }
119:
120: protected String typeString(MemberDoc member) {
121: String type = "";
122: if (member instanceof MethodDoc) {
123: type = ((MethodDoc) member).returnType().toString();
124: } else if (member instanceof FieldDoc) {
125: type = ((FieldDoc) member).type().toString();
126: }
127: return type;
128: }
129:
130: protected void printModifiers(MemberDoc member) {
131: String mod = modifierString(member);
132: // According to JLS, we should not be showing public modifier for
133: // interface methods.
134: if ((member.isField() || member.isMethod())
135: && writer instanceof ClassWriterImpl
136: && ((ClassWriterImpl) writer).getClassDoc()
137: .isInterface()) {
138: mod = Util.replaceText(mod, "public", "").trim();
139: }
140: if (mod.length() > 0) {
141: print(mod);
142: print(' ');
143: }
144: }
145:
146: protected String makeSpace(int len) {
147: if (len <= 0) {
148: return "";
149: }
150: StringBuffer sb = new StringBuffer(len);
151: for (int i = 0; i < len; i++) {
152: sb.append(' ');
153: }
154: return sb.toString();
155: }
156:
157: /**
158: * Print 'static' if static and type link.
159: */
160: protected void printStaticAndType(boolean isStatic, Type type) {
161: writer.printTypeSummaryHeader();
162: if (isStatic) {
163: print("static");
164: }
165: writer.space();
166: if (type != null) {
167: writer.printLink(new LinkInfoImpl(
168: LinkInfoImpl.CONTEXT_MEMBER, type));
169: }
170: writer.printTypeSummaryFooter();
171: }
172:
173: /**
174: * Print the modifier and type for the member in the member summary.
175: *
176: * @param member the member to print the type for.
177: * @param type the type to print.
178: */
179: protected void printModifierAndType(ProgramElementDoc member,
180: Type type) {
181: writer.printTypeSummaryHeader();
182: printModifier(member);
183: if (type == null) {
184: writer.space();
185: if (member.isClass()) {
186: print("class");
187: } else {
188: print("interface");
189: }
190: } else {
191: if (member instanceof ExecutableMemberDoc
192: && ((ExecutableMemberDoc) member).typeParameters().length > 0) {
193: //Code to avoid ugly wrapping in member summary table.
194: writer.table(0, 0, 0);
195: writer.trAlignVAlign("right", "");
196: writer.tdNowrap();
197: writer.font("-1");
198: writer.code();
199: int displayLength = ((AbstractExecutableMemberWriter) this )
200: .writeTypeParameters((ExecutableMemberDoc) member);
201: if (displayLength > 10) {
202: writer.br();
203: }
204: writer
205: .printLink(new LinkInfoImpl(
206: LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE,
207: type));
208: writer.codeEnd();
209: writer.fontEnd();
210: writer.tdEnd();
211: writer.trEnd();
212: writer.tableEnd();
213: } else {
214: writer.space();
215: writer
216: .printLink(new LinkInfoImpl(
217: LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE,
218: type));
219: }
220:
221: }
222: writer.printTypeSummaryFooter();
223: }
224:
225: private void printModifier(ProgramElementDoc member) {
226: if (member.isProtected()) {
227: print("protected ");
228: } else if (member.isPrivate()) {
229: print("private ");
230: } else if (!member.isPublic()) { // Package private
231: writer.printText("doclet.Package_private");
232: print(" ");
233: }
234: if (member.isMethod() && ((MethodDoc) member).isAbstract()) {
235: print("abstract ");
236: }
237: if (member.isStatic()) {
238: print("static");
239: }
240: }
241:
242: protected void printComment(ProgramElementDoc member) {
243: if (member.inlineTags().length > 0) {
244: writer.dd();
245: writer.printInlineComment(member);
246: }
247: }
248:
249: protected String name(ProgramElementDoc member) {
250: return member.name();
251: }
252:
253: protected void printHead(MemberDoc member) {
254: writer.h3();
255: writer.print(member.name());
256: writer.h3End();
257: }
258:
259: protected void printFullComment(ProgramElementDoc member) {
260: if (configuration().nocomment) {
261: return;
262: }
263: writer.dl();
264: print(((TagletOutputImpl) (new DeprecatedTaglet())
265: .getTagletOutput(member, writer
266: .getTagletWriterInstance(false))).toString());
267: printCommentAndTags(member);
268: writer.dlEnd();
269: }
270:
271: protected void printCommentAndTags(ProgramElementDoc member) {
272: printComment(member);
273: writer.printTags(member);
274: }
275:
276: /**
277: * Forward to containing writer
278: */
279: public void printSummaryHeader(ClassDoc cd) {
280: printedSummaryHeader = true;
281: writer.printSummaryHeader(this , cd);
282: }
283:
284: /**
285: * Forward to containing writer
286: */
287: public void printInheritedSummaryHeader(ClassDoc cd) {
288: writer.printInheritedSummaryHeader(this , cd);
289: }
290:
291: /**
292: * Forward to containing writer
293: */
294: public void printInheritedSummaryFooter(ClassDoc cd) {
295: writer.printInheritedSummaryFooter(this , cd);
296: }
297:
298: /**
299: * Forward to containing writer
300: */
301: public void printSummaryFooter(ClassDoc cd) {
302: writer.printSummaryFooter(this , cd);
303: }
304:
305: /**
306: * Return true if the given <code>ProgramElement</code> is inherited
307: * by the class that is being documented.
308: *
309: * @param ped The <code>ProgramElement</code> being checked.
310: * return true if the <code>ProgramElement</code> is being inherited and
311: * false otherwise.
312: */
313: protected boolean isInherited(ProgramElementDoc ped) {
314: if (ped.isPrivate()
315: || (ped.isPackagePrivate() && !ped.containingPackage()
316: .equals(classdoc.containingPackage()))) {
317: return false;
318: }
319: return true;
320: }
321:
322: /**
323: * Generate the code for listing the deprecated APIs. Create the table
324: * format for listing the API. Call methods from the sub-class to complete
325: * the generation.
326: */
327: protected void printDeprecatedAPI(List deprmembers,
328: String headingKey) {
329: if (deprmembers.size() > 0) {
330: writer.tableIndexSummary();
331: writer.tableHeaderStart("#CCCCFF");
332: writer.boldText(headingKey);
333: writer.tableHeaderEnd();
334: for (int i = 0; i < deprmembers.size(); i++) {
335: ProgramElementDoc member = (ProgramElementDoc) deprmembers
336: .get(i);
337: writer.trBgcolorStyle("white", "TableRowColor");
338: writer.summaryRow(0);
339: writeDeprecatedLink(member);
340: writer.br();
341: writer.printNbsps();
342: if (member.tags("deprecated").length > 0)
343: writer.printInlineDeprecatedComment(member, member
344: .tags("deprecated")[0]);
345: writer.space();
346: writer.summaryRowEnd();
347: writer.trEnd();
348: }
349: writer.tableEnd();
350: writer.space();
351: writer.p();
352: }
353: }
354:
355: /**
356: * Print use info.
357: */
358: protected void printUseInfo(Object mems, String heading) {
359: if (mems == null) {
360: return;
361: }
362: List members = (List) mems;
363: if (members.size() > 0) {
364: writer.tableIndexSummary();
365: writer.tableUseInfoHeaderStart("#CCCCFF");
366: writer.print(heading);
367: writer.tableHeaderEnd();
368: for (Iterator it = members.iterator(); it.hasNext();) {
369: ProgramElementDoc pgmdoc = (ProgramElementDoc) it
370: .next();
371: ClassDoc cd = pgmdoc.containingClass();
372:
373: writer.printSummaryLinkType(this , pgmdoc);
374: if (cd != null && !(pgmdoc instanceof ConstructorDoc)
375: && !(pgmdoc instanceof ClassDoc)) {
376: // Add class context
377: writer.bold(cd.name() + ".");
378: }
379: writeSummaryLink(
380: pgmdoc instanceof ClassDoc ? LinkInfoImpl.CONTEXT_CLASS_USE
381: : LinkInfoImpl.CONTEXT_MEMBER, cd,
382: pgmdoc);
383: writer.printSummaryLinkComment(this , pgmdoc);
384: }
385: writer.tableEnd();
386: writer.space();
387: writer.p();
388: }
389: }
390:
391: protected void navDetailLink(List members) {
392: printNavDetailLink(members.size() > 0 ? true : false);
393: }
394:
395: protected void navSummaryLink(List members,
396: VisibleMemberMap visibleMemberMap) {
397: if (members.size() > 0) {
398: printNavSummaryLink(null, true);
399: return;
400: } else {
401: ClassDoc icd = classdoc.super class();
402: while (icd != null) {
403: List inhmembers = visibleMemberMap.getMembersFor(icd);
404: if (inhmembers.size() > 0) {
405: printNavSummaryLink(icd, true);
406: return;
407: }
408: icd = icd.super class();
409: }
410: }
411: printNavSummaryLink(null, false);
412: }
413:
414: protected void serialWarning(SourcePosition pos, String key,
415: String a1, String a2) {
416: if (configuration().serialwarn) {
417: ConfigurationImpl.getInstance().getDocletSpecificMsg()
418: .warning(pos, key, a1, a2);
419: }
420: }
421:
422: public ProgramElementDoc[] eligibleMembers(
423: ProgramElementDoc[] members) {
424: return nodepr ? Util.excludeDeprecatedMembers(members)
425: : members;
426: }
427:
428: public ConfigurationImpl configuration() {
429: return writer.configuration;
430: }
431:
432: /**
433: * {@inheritDoc}
434: */
435: public void writeMemberSummary(ClassDoc classDoc,
436: ProgramElementDoc member, Tag[] firstSentenceTags,
437: boolean isFirst, boolean isLast) {
438: writer.printSummaryLinkType(this, member);
439: writeSummaryLink(classDoc, member);
440: writer.printSummaryLinkComment(this, member, firstSentenceTags);
441: }
442: }
|