Tue, 14 May 2013 10:14:53 -0700
8011668: Allow HTMLWriter.getResource to take Content args
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1997, 2013, 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.formats.html;
28 import com.sun.javadoc.*;
29 import com.sun.tools.doclets.formats.html.markup.*;
30 import com.sun.tools.doclets.internal.toolkit.*;
31 import com.sun.tools.doclets.internal.toolkit.util.*;
33 /**
34 * Print method and constructor info.
35 *
36 * <p><b>This is NOT part of any supported API.
37 * If you write code that depends on this, you do so at your own risk.
38 * This code and its internal interfaces are subject to change or
39 * deletion without notice.</b>
40 *
41 * @author Robert Field
42 * @author Atul M Dambalkar
43 * @author Bhavesh Patel (Modified)
44 */
45 public abstract class AbstractExecutableMemberWriter extends AbstractMemberWriter {
47 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer,
48 ClassDoc classdoc) {
49 super(writer, classdoc);
50 }
52 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer) {
53 super(writer);
54 }
56 /**
57 * Add the type parameters for the executable member.
58 *
59 * @param member the member to write type parameters for.
60 * @param htmltree the content tree to which the parameters will be added.
61 * @return the display length required to write this information.
62 */
63 protected int addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
64 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
65 LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS, member);
66 Content typeParameters = writer.getTypeParameterLinks(linkInfo);
67 if (linkInfo.displayLength > 0) {
68 Content linkContent = typeParameters;
69 htmltree.addContent(linkContent);
70 htmltree.addContent(writer.getSpace());
71 writer.displayLength += linkInfo.displayLength + 1;
72 }
73 return linkInfo.displayLength;
74 }
76 /**
77 * {@inheritDoc}
78 */
79 protected Content getDeprecatedLink(ProgramElementDoc member) {
80 ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
81 return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, (MemberDoc) emd,
82 emd.qualifiedName() + emd.flatSignature());
83 }
85 /**
86 * Add the summary link for the member.
87 *
88 * @param context the id of the context where the link will be printed
89 * @param cd the classDoc that we should link to
90 * @param member the member being linked to
91 * @param tdSummary the content tree to which the link will be added
92 */
93 protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member,
94 Content tdSummary) {
95 ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
96 String name = emd.name();
97 Content strong = HtmlTree.STRONG(
98 writer.getDocLink(context, cd, (MemberDoc) emd,
99 name, false));
100 Content code = HtmlTree.CODE(strong);
101 writer.displayLength = name.length();
102 addParameters(emd, false, code);
103 tdSummary.addContent(code);
104 }
106 /**
107 * Add the inherited summary link for the member.
108 *
109 * @param cd the classDoc that we should link to
110 * @param member the member being linked to
111 * @param linksTree the content tree to which the link will be added
112 */
113 protected void addInheritedSummaryLink(ClassDoc cd,
114 ProgramElementDoc member, Content linksTree) {
115 linksTree.addContent(
116 writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc) member,
117 member.name(), false));
118 }
120 /**
121 * Add the parameter for the executable member.
122 *
123 * @param member the member to write parameter for.
124 * @param param the parameter that needs to be written.
125 * @param isVarArg true if this is a link to var arg.
126 * @param tree the content tree to which the parameter information will be added.
127 */
128 protected void addParam(ExecutableMemberDoc member, Parameter param,
129 boolean isVarArg, Content tree) {
130 if (param.type() != null) {
131 Content link = writer.getLink(new LinkInfoImpl(
132 configuration, LinkInfoImpl.Kind.EXECUTABLE_MEMBER_PARAM,
133 param.type()).varargs(isVarArg));
134 tree.addContent(link);
135 }
136 if(param.name().length() > 0) {
137 tree.addContent(writer.getSpace());
138 tree.addContent(param.name());
139 }
140 }
142 /**
143 * Add the receiver annotations information.
144 *
145 * @param member the member to write receiver annotations for.
146 * @param rcvrType the receiver type.
147 * @param descList list of annotation description.
148 * @param tree the content tree to which the information will be added.
149 */
150 protected void addReceiverAnnotations(ExecutableMemberDoc member, Type rcvrType,
151 AnnotationDesc[] descList, Content tree) {
152 writer.addReceiverAnnotationInfo(member, descList, tree);
153 tree.addContent(writer.getSpace());
154 tree.addContent(rcvrType.typeName());
155 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
156 LinkInfoImpl.Kind.CLASS_SIGNATURE, rcvrType);
157 tree.addContent(writer.getTypeParameterLinks(linkInfo));
158 tree.addContent(writer.getSpace());
159 tree.addContent("this");
160 }
163 /**
164 * Add all the parameters for the executable member.
165 *
166 * @param member the member to write parameters for.
167 * @param htmltree the content tree to which the parameters information will be added.
168 */
169 protected void addParameters(ExecutableMemberDoc member, Content htmltree) {
170 addParameters(member, true, htmltree);
171 }
173 /**
174 * Add all the parameters for the executable member.
175 *
176 * @param member the member to write parameters for.
177 * @param includeAnnotations true if annotation information needs to be added.
178 * @param htmltree the content tree to which the parameters information will be added.
179 */
180 protected void addParameters(ExecutableMemberDoc member,
181 boolean includeAnnotations, Content htmltree) {
182 htmltree.addContent("(");
183 String sep = "";
184 Parameter[] params = member.parameters();
185 String indent = makeSpace(writer.displayLength);
186 if (configuration.linksource) {
187 //add spaces to offset indentation changes caused by link.
188 indent+= makeSpace(member.name().length());
189 }
190 Type rcvrType = member.receiverType();
191 if (includeAnnotations && rcvrType instanceof AnnotatedType) {
192 AnnotationDesc[] descList = rcvrType.asAnnotatedType().annotations();
193 if (descList.length > 0) {
194 addReceiverAnnotations(member, rcvrType, descList, htmltree);
195 sep = "," + DocletConstants.NL + indent;
196 }
197 }
198 int paramstart;
199 for (paramstart = 0; paramstart < params.length; paramstart++) {
200 htmltree.addContent(sep);
201 Parameter param = params[paramstart];
202 if (!param.name().startsWith("this$")) {
203 if (includeAnnotations) {
204 boolean foundAnnotations =
205 writer.addAnnotationInfo(indent.length(),
206 member, param, htmltree);
207 if (foundAnnotations) {
208 htmltree.addContent(DocletConstants.NL);
209 htmltree.addContent(indent);
210 }
211 }
212 addParam(member, param,
213 (paramstart == params.length - 1) && member.isVarArgs(), htmltree);
214 break;
215 }
216 }
218 for (int i = paramstart + 1; i < params.length; i++) {
219 htmltree.addContent(",");
220 htmltree.addContent(DocletConstants.NL);
221 htmltree.addContent(indent);
222 if (includeAnnotations) {
223 boolean foundAnnotations =
224 writer.addAnnotationInfo(indent.length(), member, params[i],
225 htmltree);
226 if (foundAnnotations) {
227 htmltree.addContent(DocletConstants.NL);
228 htmltree.addContent(indent);
229 }
230 }
231 addParam(member, params[i], (i == params.length - 1) && member.isVarArgs(),
232 htmltree);
233 }
234 htmltree.addContent(")");
235 }
237 /**
238 * Add exceptions for the executable member.
239 *
240 * @param member the member to write exceptions for.
241 * @param htmltree the content tree to which the exceptions information will be added.
242 */
243 protected void addExceptions(ExecutableMemberDoc member, Content htmltree) {
244 Type[] exceptions = member.thrownExceptionTypes();
245 if(exceptions.length > 0) {
246 LinkInfoImpl memberTypeParam = new LinkInfoImpl(configuration,
247 LinkInfoImpl.Kind.MEMBER, member);
248 int retlen = getReturnTypeLength(member);
249 writer.getTypeParameterLinks(memberTypeParam);
250 retlen += memberTypeParam.displayLength == 0 ?
251 0 : memberTypeParam.displayLength + 1;
252 String indent = makeSpace(modifierString(member).length() +
253 member.name().length() + retlen - 4);
254 htmltree.addContent(DocletConstants.NL);
255 htmltree.addContent(indent);
256 htmltree.addContent("throws ");
257 indent += " ";
258 Content link = writer.getLink(new LinkInfoImpl(configuration,
259 LinkInfoImpl.Kind.MEMBER, exceptions[0]));
260 htmltree.addContent(link);
261 for(int i = 1; i < exceptions.length; i++) {
262 htmltree.addContent(",");
263 htmltree.addContent(DocletConstants.NL);
264 htmltree.addContent(indent);
265 Content exceptionLink = writer.getLink(new LinkInfoImpl(
266 configuration, LinkInfoImpl.Kind.MEMBER, exceptions[i]));
267 htmltree.addContent(exceptionLink);
268 }
269 }
270 }
272 protected int getReturnTypeLength(ExecutableMemberDoc member) {
273 if (member instanceof MethodDoc) {
274 MethodDoc method = (MethodDoc)member;
275 Type rettype = method.returnType();
276 if (rettype.isPrimitive()) {
277 return rettype.typeName().length() +
278 rettype.dimension().length();
279 } else {
280 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
281 LinkInfoImpl.Kind.MEMBER, rettype);
282 writer.getLink(linkInfo);
283 return linkInfo.displayLength;
284 }
285 } else { // it's a constructordoc
286 return -1;
287 }
288 }
290 protected ClassDoc implementsMethodInIntfac(MethodDoc method,
291 ClassDoc[] intfacs) {
292 for (int i = 0; i < intfacs.length; i++) {
293 MethodDoc[] methods = intfacs[i].methods();
294 if (methods.length > 0) {
295 for (int j = 0; j < methods.length; j++) {
296 if (methods[j].name().equals(method.name()) &&
297 methods[j].signature().equals(method.signature())) {
298 return intfacs[i];
299 }
300 }
301 }
302 }
303 return null;
304 }
306 /**
307 * For backward compatibility, include an anchor using the erasures of the
308 * parameters. NOTE: We won't need this method anymore after we fix
309 * see tags so that they use the type instead of the erasure.
310 *
311 * @param emd the ExecutableMemberDoc to anchor to.
312 * @return the 1.4.x style anchor for the ExecutableMemberDoc.
313 */
314 protected String getErasureAnchor(ExecutableMemberDoc emd) {
315 StringBuilder buf = new StringBuilder(emd.name() + "(");
316 Parameter[] params = emd.parameters();
317 boolean foundTypeVariable = false;
318 for (int i = 0; i < params.length; i++) {
319 if (i > 0) {
320 buf.append(",");
321 }
322 Type t = params[i].type();
323 foundTypeVariable = foundTypeVariable || t.asTypeVariable() != null;
324 buf.append(t.isPrimitive() ?
325 t.typeName() : t.asClassDoc().qualifiedName());
326 buf.append(t.dimension());
327 }
328 buf.append(")");
329 return foundTypeVariable ? buf.toString() : null;
330 }
331 }