001: /*
002: * Copyright 1997-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.formats.html;
027:
028: import com.sun.tools.doclets.internal.toolkit.*;
029: import com.sun.tools.doclets.internal.toolkit.util.*;
030: import com.sun.tools.doclets.internal.toolkit.taglets.*;
031:
032: import java.io.*;
033: import com.sun.javadoc.*;
034:
035: /**
036: * Writes method documentation in HTML format.
037: *
038: * @author Robert Field
039: * @author Atul M Dambalkar
040: * @author Jamie Ho (rewrite)
041: */
042: public class MethodWriterImpl extends AbstractExecutableMemberWriter
043: implements MethodWriter, MemberSummaryWriter {
044:
045: private boolean printedSummaryHeader = false;
046:
047: /**
048: * Construct a new MethodWriterImpl.
049: *
050: * @param writer the writer for the class that the methods belong to.
051: * @param classDoc the class being documented.
052: */
053: public MethodWriterImpl(SubWriterHolderWriter writer,
054: ClassDoc classDoc) {
055: super (writer, classDoc);
056: }
057:
058: /**
059: * Construct a new MethodWriterImpl.
060: *
061: * @param writer The writer for the class that the methods belong to.
062: */
063: public MethodWriterImpl(SubWriterHolderWriter writer) {
064: super (writer);
065: }
066:
067: /**
068: * Write the methods summary header for the given class.
069: *
070: * @param classDoc the class the summary belongs to.
071: */
072: public void writeMemberSummaryHeader(ClassDoc classDoc) {
073: printedSummaryHeader = true;
074: writer.println();
075: writer
076: .println("<!-- ========== METHOD SUMMARY =========== -->");
077: writer.println();
078: writer.printSummaryHeader(this , classDoc);
079: }
080:
081: /**
082: * Write the methods summary footer for the given class.
083: *
084: * @param classDoc the class the summary belongs to.
085: */
086: public void writeMemberSummaryFooter(ClassDoc classDoc) {
087: writer.printSummaryFooter(this , classDoc);
088: }
089:
090: /**
091: * Write the inherited methods summary header for the given class.
092: *
093: * @param classDoc the class the summary belongs to.
094: */
095: public void writeInheritedMemberSummaryHeader(ClassDoc classDoc) {
096: if (!printedSummaryHeader) {
097: //We don't want inherited summary to not be under heading.
098: writeMemberSummaryHeader(classDoc);
099: writeMemberSummaryFooter(classDoc);
100: printedSummaryHeader = true;
101: }
102: writer.printInheritedSummaryHeader(this , classDoc);
103: }
104:
105: /**
106: * {@inheritDoc}
107: */
108: public void writeInheritedMemberSummary(ClassDoc classDoc,
109: ProgramElementDoc method, boolean isFirst, boolean isLast) {
110: writer.printInheritedSummaryMember(this , classDoc, method,
111: isFirst);
112: }
113:
114: /**
115: * Write the inherited methods summary footer for the given class.
116: *
117: * @param classDoc the class the summary belongs to.
118: */
119: public void writeInheritedMemberSummaryFooter(ClassDoc classDoc) {
120: writer.printInheritedSummaryFooter(this , classDoc);
121: ;
122: }
123:
124: /**
125: * Write the header for the method documentation.
126: *
127: * @param classDoc the class that the methods belong to.
128: */
129: public void writeHeader(ClassDoc classDoc, String header) {
130: writer.println();
131: writer
132: .println("<!-- ============ METHOD DETAIL ========== -->");
133: writer.println();
134: writer.anchor("method_detail");
135: writer.printTableHeadingBackground(header);
136: }
137:
138: /**
139: * Write the method header for the given method.
140: *
141: * @param method the method being documented.
142: * @param isFirst the flag to indicate whether or not the method is the
143: * first to be documented.
144: */
145: public void writeMethodHeader(MethodDoc method, boolean isFirst) {
146: if (!isFirst) {
147: writer.printMemberHeader();
148: }
149: writer.println();
150: String erasureAnchor;
151: if ((erasureAnchor = getErasureAnchor(method)) != null) {
152: writer.anchor(erasureAnchor);
153: }
154: writer.anchor(method);
155: writer.h3();
156: writer.print(method.name());
157: writer.h3End();
158: }
159:
160: /**
161: * Write the signature for the given method.
162: *
163: * @param method the method being documented.
164: */
165: public void writeSignature(MethodDoc method) {
166: writer.displayLength = 0;
167: writer.pre();
168: writer.writeAnnotationInfo(method);
169: printModifiers(method);
170: writeTypeParameters(method);
171: printReturnType(method);
172: if (configuration().linksource) {
173: writer.printSrcLink(method, method.name());
174: } else {
175: bold(method.name());
176: }
177: writeParameters(method);
178: writeExceptions(method);
179: writer.preEnd();
180: writer.dl();
181: }
182:
183: /**
184: * Write the deprecated output for the given method.
185: *
186: * @param method the method being documented.
187: */
188: public void writeDeprecated(MethodDoc method) {
189: String output = ((TagletOutputImpl) (new DeprecatedTaglet())
190: .getTagletOutput(method, writer
191: .getTagletWriterInstance(false))).toString();
192: if (output != null && output.trim().length() > 0) {
193: writer.print(output);
194: }
195: }
196:
197: /**
198: * Write the comments for the given method.
199: *
200: * @param method the method being documented.
201: */
202: public void writeComments(Type holder, MethodDoc method) {
203: ClassDoc holderClassDoc = holder.asClassDoc();
204: if (method.inlineTags().length > 0) {
205: if (holder.asClassDoc().equals(classdoc)
206: || (!(holderClassDoc.isPublic() || Util.isLinkable(
207: holderClassDoc, configuration())))) {
208: writer.dd();
209: writer.printInlineComment(method);
210: } else {
211: String classlink = writer.codeText(writer.getDocLink(
212: LinkInfoImpl.CONTEXT_METHOD_DOC_COPY, holder
213: .asClassDoc(), method, holder
214: .asClassDoc().isIncluded() ? holder
215: .typeName() : holder
216: .qualifiedTypeName(), false));
217: writer.dd();
218: writer
219: .boldText(
220: holder.asClassDoc().isClass() ? "doclet.Description_From_Class"
221: : "doclet.Description_From_Interface",
222: classlink);
223: writer.ddEnd();
224: writer.dd();
225: writer.printInlineComment(method);
226: }
227: }
228: }
229:
230: /**
231: * Write the tag output for the given method.
232: *
233: * @param method the method being documented.
234: */
235: public void writeTags(MethodDoc method) {
236: writer.printTags(method);
237: }
238:
239: /**
240: * Write the method footer.
241: */
242: public void writeMethodFooter() {
243: writer.ddEnd();
244: writer.dlEnd();
245: }
246:
247: /**
248: * Write the footer for the method documentation.
249: *
250: * @param classDoc the class that the methods belong to.
251: */
252: public void writeFooter(ClassDoc classDoc) {
253: //No footer to write for method documentation
254: }
255:
256: /**
257: * Close the writer.
258: */
259: public void close() throws IOException {
260: writer.close();
261: }
262:
263: public int getMemberKind() {
264: return VisibleMemberMap.METHODS;
265: }
266:
267: public void printSummaryLabel(ClassDoc cd) {
268: writer.boldText("doclet.Method_Summary");
269: }
270:
271: public void printSummaryAnchor(ClassDoc cd) {
272: writer.anchor("method_summary");
273: }
274:
275: public void printInheritedSummaryAnchor(ClassDoc cd) {
276: writer.anchor("methods_inherited_from_class_"
277: + ConfigurationImpl.getInstance().getClassName(cd));
278: }
279:
280: public void printInheritedSummaryLabel(ClassDoc cd) {
281: String classlink = writer.getPreQualifiedClassLink(
282: LinkInfoImpl.CONTEXT_MEMBER, cd, false);
283: writer.bold();
284: String key = cd.isClass() ? "doclet.Methods_Inherited_From_Class"
285: : "doclet.Methods_Inherited_From_Interface";
286: writer.printText(key, classlink);
287: writer.boldEnd();
288: }
289:
290: protected void printSummaryType(ProgramElementDoc member) {
291: MethodDoc meth = (MethodDoc) member;
292: printModifierAndType(meth, meth.returnType());
293: }
294:
295: protected static void printOverridden(HtmlDocletWriter writer,
296: Type overriddenType, MethodDoc method) {
297: if (writer.configuration.nocomment) {
298: return;
299: }
300: ClassDoc holderClassDoc = overriddenType.asClassDoc();
301: if (!(holderClassDoc.isPublic() || Util.isLinkable(
302: holderClassDoc, writer.configuration()))) {
303: //This is an implementation detail that should not be documented.
304: return;
305: }
306: if (overriddenType.asClassDoc().isIncluded()
307: && !method.isIncluded()) {
308: //The class is included but the method is not. That means that it
309: //is not visible so don't document this.
310: return;
311: }
312: String label = "doclet.Overrides";
313: int context = LinkInfoImpl.CONTEXT_METHOD_OVERRIDES;
314:
315: if (method != null) {
316: if (overriddenType.asClassDoc().isAbstract()
317: && method.isAbstract()) {
318: //Abstract method is implemented from abstract class,
319: //not overridden
320: label = "doclet.Specified_By";
321: context = LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY;
322: }
323: String overriddenTypeLink = writer
324: .codeText(writer.getLink(new LinkInfoImpl(context,
325: overriddenType)));
326: String name = method.name();
327: writer.dt();
328: writer.boldText(label);
329: writer.dd();
330: String methLink = writer.codeText(writer
331: .getLink(new LinkInfoImpl(
332: LinkInfoImpl.CONTEXT_MEMBER, overriddenType
333: .asClassDoc(), writer
334: .getAnchor(method), name, false)));
335: writer.printText("doclet.in_class", methLink,
336: overriddenTypeLink);
337: }
338: }
339:
340: /**
341: * Parse the <Code> tag and return the text.
342: */
343: protected String parseCodeTag(String tag) {
344: if (tag == null) {
345: return "";
346: }
347:
348: String lc = tag.toLowerCase();
349: int begin = lc.indexOf("<code>");
350: int end = lc.indexOf("</code>");
351: if (begin == -1 || end == -1 || end <= begin) {
352: return tag;
353: } else {
354: return tag.substring(begin + 6, end);
355: }
356: }
357:
358: protected static void printImplementsInfo(HtmlDocletWriter writer,
359: MethodDoc method) {
360: if (writer.configuration.nocomment) {
361: return;
362: }
363: ImplementedMethods implementedMethodsFinder = new ImplementedMethods(
364: method, writer.configuration);
365: MethodDoc[] implementedMethods = implementedMethodsFinder
366: .build();
367: for (int i = 0; i < implementedMethods.length; i++) {
368: MethodDoc implementedMeth = implementedMethods[i];
369: Type intfac = implementedMethodsFinder
370: .getMethodHolder(implementedMeth);
371: String methlink = "";
372: String intfaclink = writer.codeText(writer
373: .getLink(new LinkInfoImpl(
374: LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY,
375: intfac)));
376: writer.dt();
377: writer.boldText("doclet.Specified_By");
378: writer.dd();
379: methlink = writer.codeText(writer.getDocLink(
380: LinkInfoImpl.CONTEXT_MEMBER, implementedMeth,
381: implementedMeth.name(), false));
382: writer.printText("doclet.in_interface", methlink,
383: intfaclink);
384: }
385:
386: }
387:
388: protected void printReturnType(MethodDoc method) {
389: Type type = method.returnType();
390: if (type != null) {
391: writer.printLink(new LinkInfoImpl(
392: LinkInfoImpl.CONTEXT_RETURN_TYPE, type));
393: print(' ');
394: }
395: }
396:
397: protected void printNavSummaryLink(ClassDoc cd, boolean link) {
398: if (link) {
399: writer.printHyperLink("", (cd == null) ? "method_summary"
400: : "methods_inherited_from_class_"
401: + ConfigurationImpl.getInstance()
402: .getClassName(cd),
403: ConfigurationImpl.getInstance().getText(
404: "doclet.navMethod"));
405: } else {
406: writer.printText("doclet.navMethod");
407: }
408: }
409:
410: protected void printNavDetailLink(boolean link) {
411: if (link) {
412: writer.printHyperLink("", "method_detail",
413: ConfigurationImpl.getInstance().getText(
414: "doclet.navMethod"));
415: } else {
416: writer.printText("doclet.navMethod");
417: }
418: }
419: }
|