001: /*
002: * Copyright 1997-2005 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.javadoc.*;
029:
030: /**
031: * Print method and constructor info.
032: *
033: * @author Robert Field
034: * @author Atul M Dambalkar
035: */
036: public abstract class AbstractExecutableMemberWriter extends
037: AbstractMemberWriter {
038:
039: public AbstractExecutableMemberWriter(SubWriterHolderWriter writer,
040: ClassDoc classdoc) {
041: super (writer, classdoc);
042: }
043:
044: public AbstractExecutableMemberWriter(SubWriterHolderWriter writer) {
045: super (writer);
046: }
047:
048: /**
049: * Write the type parameters for the executable member.
050: *
051: * @param member the member to write type parameters for.
052: * @return the display length required to write this information.
053: */
054: protected int writeTypeParameters(ExecutableMemberDoc member) {
055: LinkInfoImpl linkInfo = new LinkInfoImpl(
056: LinkInfoImpl.CONTEXT_MEMBER_TYPE_PARAMS, member, false);
057: String typeParameters = writer.getTypeParameterLinks(linkInfo);
058: if (linkInfo.displayLength > 0) {
059: writer.print(typeParameters + " ");
060: writer.displayLength += linkInfo.displayLength + 1;
061: }
062: return linkInfo.displayLength;
063: }
064:
065: protected void writeSignature(ExecutableMemberDoc member) {
066: writer.displayLength = 0;
067: writer.pre();
068: writer.writeAnnotationInfo(member);
069: printModifiers(member);
070: writeTypeParameters(member);
071: if (configuration().linksource
072: && member.position().line() != classdoc.position()
073: .line()) {
074: writer.printSrcLink(member, member.name());
075: } else {
076: bold(member.name());
077: }
078: writeParameters(member);
079: writeExceptions(member);
080: writer.preEnd();
081: }
082:
083: protected void writeDeprecatedLink(ProgramElementDoc member) {
084: ExecutableMemberDoc emd = (ExecutableMemberDoc) member;
085: writer.printDocLink(LinkInfoImpl.CONTEXT_MEMBER,
086: (MemberDoc) emd, emd.qualifiedName()
087: + emd.flatSignature(), false);
088: }
089:
090: protected void writeSummaryLink(int context, ClassDoc cd,
091: ProgramElementDoc member) {
092: ExecutableMemberDoc emd = (ExecutableMemberDoc) member;
093: String name = emd.name();
094: writer.bold();
095: writer.printDocLink(context, cd, (MemberDoc) emd, name, false);
096: writer.boldEnd();
097: writer.displayLength = name.length();
098: writeParameters(emd, false);
099: }
100:
101: protected void writeInheritedSummaryLink(ClassDoc cd,
102: ProgramElementDoc member) {
103: writer.printDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd,
104: (MemberDoc) member, member.name(), false);
105: }
106:
107: protected void writeParam(ExecutableMemberDoc member,
108: Parameter param, boolean isVarArg) {
109: if (param.type() != null) {
110: writer.printLink(new LinkInfoImpl(
111: LinkInfoImpl.CONTEXT_EXECUTABLE_MEMBER_PARAM, param
112: .type(), isVarArg));
113: }
114: if (param.name().length() > 0) {
115: writer.space();
116: writer.print(param.name());
117: }
118: }
119:
120: protected void writeParameters(ExecutableMemberDoc member) {
121: writeParameters(member, true);
122: }
123:
124: protected void writeParameters(ExecutableMemberDoc member,
125: boolean includeAnnotations) {
126: print('(');
127: Parameter[] params = member.parameters();
128: String indent = makeSpace(writer.displayLength);
129: if (configuration().linksource) {
130: //add spaces to offset indentation changes caused by link.
131: indent += makeSpace(member.name().length());
132: }
133: int paramstart;
134: for (paramstart = 0; paramstart < params.length; paramstart++) {
135: Parameter param = params[paramstart];
136: if (!param.name().startsWith("this$")) {
137: if (includeAnnotations) {
138: boolean foundAnnotations = writer
139: .writeAnnotationInfo(indent.length(),
140: member, param);
141: if (foundAnnotations) {
142: writer.println();
143: writer.print(indent);
144: }
145: }
146: writeParam(member, param,
147: (paramstart == params.length - 1)
148: && member.isVarArgs());
149: break;
150: }
151: }
152:
153: for (int i = paramstart + 1; i < params.length; i++) {
154: writer.print(',');
155: writer.println();
156: writer.print(indent);
157: if (includeAnnotations) {
158: boolean foundAnnotations = writer.writeAnnotationInfo(
159: indent.length(), member, params[i]);
160: if (foundAnnotations) {
161: writer.println();
162: writer.print(indent);
163: }
164: }
165: writeParam(member, params[i], (i == params.length - 1)
166: && member.isVarArgs());
167: }
168: writer.print(')');
169: }
170:
171: protected void writeExceptions(ExecutableMemberDoc member) {
172: Type[] exceptions = member.thrownExceptionTypes();
173: if (exceptions.length > 0) {
174: LinkInfoImpl memberTypeParam = new LinkInfoImpl(
175: LinkInfoImpl.CONTEXT_MEMBER, member, false);
176: int retlen = getReturnTypeLength(member);
177: writer.getTypeParameterLinks(memberTypeParam);
178: retlen += memberTypeParam.displayLength == 0 ? 0
179: : memberTypeParam.displayLength + 1;
180: String indent = makeSpace(modifierString(member).length()
181: + member.name().length() + retlen - 4);
182: writer.println();
183: writer.print(indent);
184: writer.print("throws ");
185: indent += " ";
186: writer.printLink(new LinkInfoImpl(
187: LinkInfoImpl.CONTEXT_MEMBER, exceptions[0]));
188: for (int i = 1; i < exceptions.length; i++) {
189: writer.println(",");
190: writer.print(indent);
191: writer.printLink(new LinkInfoImpl(
192: LinkInfoImpl.CONTEXT_MEMBER, exceptions[i]));
193: }
194: }
195: }
196:
197: protected int getReturnTypeLength(ExecutableMemberDoc member) {
198: if (member instanceof MethodDoc) {
199: MethodDoc method = (MethodDoc) member;
200: Type rettype = method.returnType();
201: if (rettype.isPrimitive()) {
202: return rettype.typeName().length()
203: + rettype.dimension().length();
204: } else {
205: LinkInfoImpl linkInfo = new LinkInfoImpl(
206: LinkInfoImpl.CONTEXT_MEMBER, rettype);
207: writer.getLink(linkInfo);
208: return linkInfo.displayLength;
209: }
210: } else { // it's a constructordoc
211: return -1;
212: }
213: }
214:
215: protected ClassDoc implements MethodInIntfac(MethodDoc method,
216: ClassDoc[] intfacs) {
217: for (int i = 0; i < intfacs.length; i++) {
218: MethodDoc[] methods = intfacs[i].methods();
219: if (methods.length > 0) {
220: for (int j = 0; j < methods.length; j++) {
221: if (methods[j].name().equals(method.name())
222: && methods[j].signature().equals(
223: method.signature())) {
224: return intfacs[i];
225: }
226: }
227: }
228: }
229: return null;
230: }
231:
232: /**
233: * For backward compatibility, include an anchor using the erasures of the
234: * parameters. NOTE: We won't need this method anymore after we fix
235: * see tags so that they use the type instead of the erasure.
236: *
237: * @param emd the ExecutableMemberDoc to anchor to.
238: * @return the 1.4.x style anchor for the ExecutableMemberDoc.
239: */
240: protected String getErasureAnchor(ExecutableMemberDoc emd) {
241: StringBuffer buf = new StringBuffer(emd.name() + "(");
242: Parameter[] params = emd.parameters();
243: boolean foundTypeVariable = false;
244: for (int i = 0; i < params.length; i++) {
245: if (i > 0) {
246: buf.append(",");
247: }
248: Type t = params[i].type();
249: foundTypeVariable = foundTypeVariable
250: || t.asTypeVariable() != null;
251: buf.append(t.isPrimitive() ? t.typeName() : t.asClassDoc()
252: .qualifiedName());
253: buf.append(t.dimension());
254: }
255: buf.append(")");
256: return foundTypeVariable ? buf.toString() : null;
257: }
258: }
|