KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > java > JavaCompletionDoc


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.editor.java;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.lang.reflect.Modifier JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26 import java.net.URI JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.Hashtable JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import javax.lang.model.element.Element;
31 import javax.lang.model.element.ElementKind;
32 import javax.lang.model.element.ExecutableElement;
33 import javax.lang.model.element.TypeElement;
34 import javax.lang.model.element.VariableElement;
35 import javax.lang.model.type.ArrayType;
36 import javax.lang.model.type.DeclaredType;
37 import javax.lang.model.type.TypeMirror;
38 import javax.swing.AbstractAction JavaDoc;
39 import javax.swing.Action JavaDoc;
40 import com.sun.javadoc.*;
41 import com.sun.javadoc.AnnotationDesc.ElementValuePair;
42 import javax.lang.model.type.TypeKind;
43 import org.netbeans.api.java.source.CancellableTask;
44 import org.netbeans.api.java.source.ClasspathInfo;
45 import org.netbeans.api.java.source.CompilationController;
46 import org.netbeans.api.java.source.ElementHandle;
47 import org.netbeans.api.java.source.ElementUtilities;
48 import org.netbeans.api.java.source.JavaSource;
49 import org.netbeans.api.java.source.JavaSource.Phase;
50 import org.netbeans.api.java.source.SourceUtils;
51 import org.netbeans.api.java.source.UiUtils;
52 import org.netbeans.spi.editor.completion.CompletionDocumentation;
53 import org.openide.filesystems.FileObject;
54 import org.openide.util.Exceptions;
55 import org.openide.util.NbBundle;
56
57 /**
58  *
59  * @author Dusan Balek
60  */

61 public class JavaCompletionDoc implements CompletionDocumentation {
62
63     private ClasspathInfo cpInfo;
64     private Doc doc;
65     private String JavaDoc content = null;
66     private Hashtable JavaDoc<String JavaDoc, ElementHandle<? extends Element>> links = new Hashtable JavaDoc<String JavaDoc, ElementHandle<? extends Element>>();
67     private int linkCounter = 0;
68     private URL JavaDoc docURL = null;
69     private AbstractAction JavaDoc goToSource = null;
70
71     private static final String JavaDoc PARAM_TAG = "@param"; //NOI18N
72
private static final String JavaDoc RETURN_TAG = "@return"; //NOI18N
73
private static final String JavaDoc THROWS_TAG = "@throws"; //NOI18N
74
private static final String JavaDoc SEE_TAG = "@see"; //NOI18N
75
private static final String JavaDoc SINCE_TAG = "@since"; //NOI18N
76
private static final String JavaDoc INHERIT_DOC_TAG = "@inheritDoc"; //NOI18N
77
private static final String JavaDoc LINKPLAIN_TAG = "@linkplain"; //NOI18N
78
private static final String JavaDoc CODE_TAG = "@code"; //NOI18N
79
private static final String JavaDoc DEPRECATED_TAG = "@deprecated"; //NOI18N
80

81     public static final JavaCompletionDoc create(CompilationController controller, Element element) {
82         return new JavaCompletionDoc(controller, element, null);
83     }
84     
85     private JavaCompletionDoc(CompilationController controller, Element element, URL JavaDoc url) {
86         ElementUtilities eu = controller.getElementUtilities();
87         this.cpInfo = controller.getClasspathInfo();
88         this.doc = eu.javaDocFor(element);
89         if (element != null) {
90             final FileObject fo = SourceUtils.getFile(element, controller.getClasspathInfo());
91             if (fo != null) {
92                 final ElementHandle<? extends Element> handle = ElementHandle.create(element);
93                 goToSource = new AbstractAction JavaDoc() {
94                     public void actionPerformed(ActionEvent JavaDoc evt) {
95                         UiUtils.open(fo, handle);
96                     }
97                 };
98             }
99             if (url != null) {
100                 docURL = url;
101             } else {
102                 docURL = SourceUtils.getJavadoc(element, cpInfo);
103                 if (docURL != null) {
104                     CharSequence JavaDoc fragment = getFragment(element);
105                     if (fragment.length() > 0) {
106                         try {
107                             docURL = new URL JavaDoc(docURL.toExternalForm() + "#" + fragment); //NOI18N
108
} catch (MalformedURLException JavaDoc e) {}
109                     }
110                 }
111             }
112         }
113         this.content = prepareContent(eu);
114     }
115
116     public String JavaDoc getText() {
117         return content;
118     }
119
120     public URL JavaDoc getURL() {
121         return docURL;
122     }
123
124     public CompletionDocumentation resolveLink(final String JavaDoc link) {
125         final CompletionDocumentation[] ret = new CompletionDocumentation[1];
126         try {
127             final ElementHandle<? extends Element> linkDoc = links.get(link);
128             FileObject fo = linkDoc != null ? SourceUtils.getFile(linkDoc, cpInfo) : null;
129             JavaSource js = fo != null ? JavaSource.forFileObject(fo) : JavaSource.create(cpInfo);
130             if (js != null) {
131                 js.runUserActionTask(new CancellableTask<CompilationController>() {
132                     public void run(CompilationController controller) throws IOException JavaDoc {
133                         controller.toPhase(Phase.ELEMENTS_RESOLVED);
134                         if (linkDoc != null) {
135                             ret[0] = new JavaCompletionDoc(controller, linkDoc.resolve(controller), null);
136                         } else {
137                             int idx = link.indexOf('#'); //NOI18N
138
URI JavaDoc uri = URI.create(idx < 0 ? link : link.substring(0, idx));
139                             if (uri != null) {
140                                 if (!uri.isAbsolute())
141                                     uri = uri.normalize();
142                                 String JavaDoc path = uri.toString();
143                                 int startIdx = path.lastIndexOf(".."); //NOI18N
144
startIdx = startIdx < 0 ? 0 : startIdx + 3;
145                                 int endIdx = path.lastIndexOf('.'); //NOI18N
146
if (endIdx >= 0)
147                                     path = path.substring(startIdx, endIdx);
148                                 String JavaDoc clsName = path.replace('/', '.'); //NOI18N
149
Element e = controller.getElements().getTypeElement(clsName);
150                                 if (e != null) {
151                                     if (idx >= 0) {
152                                         String JavaDoc fragment = link.substring(idx + 1);
153                                         idx = fragment.indexOf('('); //NOI18N
154
String JavaDoc name = idx < 0 ? fragment : fragment.substring(0, idx);
155                                         for (Element member : e.getEnclosedElements()) {
156                                             if (member.getSimpleName().contentEquals(name) && fragment.contentEquals(getFragment(member))) {
157                                                 e = member;
158                                                 break;
159                                             }
160                                         }
161                                     }
162                                     ret[0] = new JavaCompletionDoc(controller, e, new URL JavaDoc(docURL, link));
163                                 }
164                             }
165                         }
166                     }
167                     public void cancel() {
168                     }
169                 }, true);
170             }
171         } catch (IOException JavaDoc ioe) {
172             Exceptions.printStackTrace(ioe);
173         }
174         return ret[0];
175     }
176
177     public Action JavaDoc getGotoSourceAction() {
178         return goToSource;
179     }
180     
181     private String JavaDoc prepareContent(ElementUtilities eu) {
182         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
183         if (doc != null) {
184             if (doc instanceof ProgramElementDoc) {
185                 sb.append(getContainingClassOrPacakgeHeader(eu, (ProgramElementDoc)doc));
186             }
187             if (doc.isMethod() || doc.isConstructor() || doc.isAnnotationTypeElement()) {
188                 sb.append(getMethodHeader(eu, (ExecutableMemberDoc)doc));
189             } else if (doc.isField() || doc.isEnumConstant()) {
190                 sb.append(getFieldHeader(eu, (FieldDoc)doc));
191             } else if (doc.isClass() || doc.isInterface() || doc.isAnnotationType()) {
192                 sb.append(getClassHeader(eu, (ClassDoc)doc));
193             }
194             sb.append("<p>"); //NOI18N
195
if (doc.commentText().length() > 0 || doc.tags().length > 0) {
196                 sb.append(getDeprecatedTag(eu, doc));
197                 sb.append(inlineTags(eu, doc, doc.inlineTags()));
198                 sb.append("</p><p>"); //NOI18N
199
sb.append(getTags(eu, doc));
200             } else {
201                 String JavaDoc jdText = docURL != null ? HTMLJavadocParser.getJavadocText(docURL, false) : null;
202                 if (jdText != null)
203                     sb.append(jdText);
204                 else
205                     sb.append(NbBundle.getMessage(JavaCompletionDoc.class, "javadoc_content_not_found")); //NOI18N
206
}
207             sb.append("</p>"); //NOI18N
208
} else {
209             sb.append(NbBundle.getMessage(JavaCompletionDoc.class, "javadoc_content_not_found")); //NOI18N
210
}
211         return sb.toString();
212     }
213     
214     private CharSequence JavaDoc getContainingClassOrPacakgeHeader(ElementUtilities eu, ProgramElementDoc peDoc) {
215         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
216         ClassDoc cls = peDoc.containingClass();
217         if (cls != null) {
218             Element e = eu.elementFor(cls);
219             if (e != null) {
220                 switch(e.getEnclosingElement().getKind()) {
221                     case ANNOTATION_TYPE:
222                     case CLASS:
223                     case ENUM:
224                     case INTERFACE:
225                     case PACKAGE:
226                         if (cls.containingClass() != null || cls.containingPackage() != null) {
227                             sb.append("<font size='+0'><b>"); //NOI18N
228
createLink(sb, e, cls.qualifiedName());
229                             sb.append("</b></font>"); //NOI18N)
230
}
231                 }
232             }
233         } else {
234             PackageDoc pkg = peDoc.containingPackage();
235             if (pkg != null) {
236                 sb.append("<font size='+0'><b>"); //NOI18N
237
createLink(sb, eu.elementFor(pkg), pkg.name());
238                 sb.append("</b></font>"); //NOI18N)
239
}
240         }
241         return sb;
242     }
243     
244     private CharSequence JavaDoc getMethodHeader(ElementUtilities eu, ExecutableMemberDoc mdoc) {
245         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
246         sb.append("<pre>"); //NOI18N
247
sb.append(getAnnotations(eu, mdoc));
248         int len = sb.length();
249         sb.append(Modifier.toString(mdoc.modifierSpecifier() &~ Modifier.NATIVE));
250         len = sb.length() - len;
251         TypeVariable[] tvars = mdoc.typeParameters();
252         if (tvars.length > 0) {
253             if (len > 0) {
254                 sb.append(' '); //NOI18N
255
len++;
256             }
257             sb.append("&lt;"); //NOI18N
258
for (int i = 0; i < tvars.length; i++) {
259                 len += appendType(eu, sb, tvars[i], false, true);
260                 if (i < tvars.length - 1) {
261                     sb.append(","); //NOI18N
262
len++;
263                 }
264             }
265             sb.append("&gt;"); //NOI18N
266
len += 2;
267         }
268         if (!mdoc.isConstructor()) {
269             if (len > 0) {
270                 sb.append(' '); //NOI18N
271
len++;
272             }
273             len += appendType(eu, sb, ((MethodDoc)mdoc).returnType(), false, false);
274         }
275         String JavaDoc name = mdoc.name();
276         len += name.length();
277         sb.append(" <b>").append(name).append("</b>"); //NOI18N
278
if (!mdoc.isAnnotationTypeElement()) {
279             sb.append('('); //NOI18N
280
len++;
281             Parameter[] params = mdoc.parameters();
282             for(int i = 0; i < params.length; i++) {
283                 boolean varArg = i == params.length - 1 && mdoc.isVarArgs();
284                 appendType(eu, sb, params[i].type(), varArg, false);
285                 sb.append(' ').append(params[i].name()); //NOI18N
286
String JavaDoc dim = params[i].type().dimension();
287                 if (dim.length() > 0) {
288                     if (varArg)
289                         dim = dim.substring(2) + "..."; //NOI18N
290
}
291                 if (i < params.length - 1) {
292                     sb.append(",\n"); //NOI18N
293
appendSpace(sb, len);
294                 }
295             }
296             sb.append(')'); //NOI18N
297
}
298         Type[] exs = mdoc.thrownExceptionTypes();
299         if (exs.length > 0) {
300             sb.append("\nthrows "); //NOI18N
301
for (int i = 0; i < exs.length; i++) {
302                 appendType(eu, sb, exs[i], false, false);
303                 if (i < exs.length - 1)
304                     sb.append(", "); //NOI18N
305
}
306         }
307         sb.append("</pre>"); //NOI18N
308
return sb;
309     }
310     
311     private CharSequence JavaDoc getFieldHeader(ElementUtilities eu, FieldDoc fdoc) {
312         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
313         sb.append("<pre>"); //NOI18N
314
sb.append(getAnnotations(eu, fdoc));
315         int len = sb.length();
316         sb.append(fdoc.modifiers());
317         len = sb.length() - len;
318         if (len > 0)
319             sb.append(' '); //NOI18N
320
appendType(eu, sb, fdoc.type(), false, false);
321         sb.append(" <b>").append(fdoc.name()).append("</b>"); //NOI18N
322
sb.append("</pre>"); //NOI18N
323
return sb;
324     }
325     
326     private CharSequence JavaDoc getClassHeader(ElementUtilities eu, ClassDoc cdoc) {
327         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
328         sb.append("<pre>"); //NOI18N
329
sb.append(getAnnotations(eu, cdoc));
330         int mods = cdoc.modifierSpecifier() & ~Modifier.INTERFACE;
331         if (cdoc.isEnum())
332             mods &= ~Modifier.FINAL;
333         sb.append(Modifier.toString(mods));
334         if (sb.length() > 0)
335             sb.append(' '); //NOI18N
336
if (cdoc.isAnnotationType())
337             sb.append("@interface "); //NOI18N
338
else if (cdoc.isEnum())
339             sb.append("enum "); //NOI18N
340
else if (cdoc.isInterface())
341             sb.append("interface "); //NOI18N
342
else
343             sb.append("class "); //NOI18N
344
sb.append("<b>").append(cdoc.name()); //NOI18N
345
TypeVariable[] tvars = cdoc.typeParameters();
346         if (tvars.length > 0) {
347             sb.append("&lt;"); //NOI18N
348
for (int i = 0; i < tvars.length; i++) {
349                 appendType(eu, sb, tvars[i], false, true);
350                 if (i < tvars.length - 1)
351                     sb.append(","); //NOI18N
352
}
353             sb.append("&gt;"); //NOI18N
354
}
355         sb.append("</b>"); //NOi18N
356
if (!cdoc.isAnnotationType()) {
357             if (cdoc.isClass()) {
358                 Type supercls = cdoc.superclassType();
359                 if (supercls != null) {
360                     sb.append("\nextends "); //NOI18N
361
appendType(eu, sb, supercls, false, false);
362                 }
363                 
364             }
365             Type[] ifaces = cdoc.interfaceTypes();
366             if (ifaces.length > 0) {
367                 sb.append(cdoc.isInterface() ? "\nextends " : "\nimplements "); //NOI18N
368
for (int i = 0; i < ifaces.length; i++) {
369                     appendType(eu, sb, ifaces[i], false, false);
370                     if (i < ifaces.length - 1)
371                         sb.append(", "); //NOI18N
372
}
373             }
374         }
375         sb.append("</pre>"); //NOI18N
376
return sb;
377     }
378     
379     private CharSequence JavaDoc getAnnotations(ElementUtilities eu, ProgramElementDoc peDoc) {
380         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
381         for (AnnotationDesc annotationDesc : peDoc.annotations()) {
382             AnnotationTypeDoc annotationType = annotationDesc.annotationType();
383             if (annotationType != null) {
384                 appendType(eu, sb, annotationType, false, false);
385                 ElementValuePair[] pairs = annotationDesc.elementValues();
386                 if (pairs.length > 0) {
387                     sb.append('('); //NOI18N
388
for (int i = 0; i < pairs.length; i++) {
389                         AnnotationTypeElementDoc ated = pairs[i].element();
390                         createLink(sb, eu.elementFor(ated), ated.name());
391                         sb.append('='); //NOI18N
392
appendAnnotationValue(eu, sb, pairs[i].value());
393                         if (i < pairs.length - 1)
394                             sb.append(","); //NOI18N
395
}
396                     sb.append(')'); //NOI18N
397
}
398                 sb.append('\n'); //NOI18N
399
}
400         }
401         return sb;
402     }
403     
404     private void appendAnnotationValue(ElementUtilities eu, StringBuilder JavaDoc sb, AnnotationValue av) {
405         Object JavaDoc value = av.value();
406         if (value instanceof AnnotationValue[]) {
407             int length = ((AnnotationValue[])value).length;
408             if (length > 1)
409                 sb.append('{'); //NOI18N
410
for(int i = 0; i < ((AnnotationValue[])value).length; i++) {
411                 appendAnnotationValue(eu, sb, ((AnnotationValue[])value)[i]);
412                 if (i < ((AnnotationValue[])value).length - 1)
413                     sb.append(","); //NOI18N
414
}
415             if (length > 1)
416                 sb.append('}'); //NOI18N
417
} else if (value instanceof Doc) {
418             createLink(sb, eu.elementFor((Doc)value), ((Doc)value).name());
419         } else {
420             sb.append(value.toString());
421         }
422     }
423     
424     private CharSequence JavaDoc getTags(ElementUtilities eu, Doc doc) {
425         StringBuilder JavaDoc see = new StringBuilder JavaDoc();
426         StringBuilder JavaDoc par = new StringBuilder JavaDoc();
427         StringBuilder JavaDoc thr = new StringBuilder JavaDoc();
428         StringBuilder JavaDoc ret = new StringBuilder JavaDoc();
429         String JavaDoc since = null;
430         for (Tag tag : doc.tags()) {
431             if (PARAM_TAG.equals(tag.kind())) {
432                 par.append("<code>").append(((ParamTag)tag).parameterName()).append("</code>"); //NOI18N
433
Tag[] its = tag.inlineTags();
434                 if (its.length > 0) {
435                     par.append(" - "); //NOI18N
436
par.append(inlineTags(eu, doc, its));
437                 }
438                 par.append("<br>"); //NOI18N
439
} else if (THROWS_TAG.equals(tag.kind())) {
440                 thr.append("<code>"); //NOI18N
441
Type exType = ((ThrowsTag)tag).exceptionType();
442                 if (exType != null)
443                     createLink(thr, eu.elementFor(exType.asClassDoc()), exType.simpleTypeName());
444                 else
445                     thr.append(((ThrowsTag)tag).exceptionName());
446                 thr.append("</code>"); //NOI18N
447
Tag[] its = tag.inlineTags();
448                 if (its.length > 0) {
449                     thr.append(" - "); //NOI18N
450
thr.append(inlineTags(eu, doc, its));
451                 }
452                 thr.append("<br>"); //NOI18N
453
} else if (RETURN_TAG.equals(tag.kind())) {
454                 ret.append(inlineTags(eu, doc, tag.inlineTags()));
455                 ret.append("<br>"); //NOI18N
456
} else if (SEE_TAG.equals(tag.kind())) {
457                 SeeTag stag = (SeeTag)tag;
458                 ClassDoc refClass = stag.referencedClass();
459                 String JavaDoc className = stag.referencedClassName();
460                 String JavaDoc memberName = stag.referencedMemberName();
461                 String JavaDoc label = stag.label();
462                 if (memberName != null) {
463                     if (refClass != null) {
464                         createLink(see, eu.elementFor(stag.referencedMember()), "<code>" + (label != null && label.length() > 0 ? label : (refClass.simpleTypeName() + "." + memberName)) + "</code>"); //NOI18N
465
} else {
466                         see.append(className);
467                         see.append('.'); //NOI18N
468
see.append(memberName);
469                     }
470                     see.append(", "); //NOI18N
471
} else if (className != null) {
472                     if (refClass != null) {
473                         createLink(see, eu.elementFor(refClass), "<code>" + (label != null && label.length() > 0 ? label : refClass.simpleTypeName()) + "</code>"); //NOI18N
474
} else {
475                         see.append(className);
476                     }
477                     see.append(", "); //NOI18N
478
} else {
479                     see.append(stag.text()).append(", "); //NOI18N
480
}
481             } else if (SINCE_TAG.equals(tag.kind())) {
482                 since = tag.text();
483             }
484         }
485         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
486         if (par.length() > 0) {
487             sb.append("<b>").append(NbBundle.getMessage(JavaCompletionDoc.class, "JCD-params")).append("</b><blockquote>").append(par).append("</blockquote>"); //NOI18N
488
}
489         if (ret.length() > 0) {
490             sb.append("<b>").append(NbBundle.getMessage(JavaCompletionDoc.class, "JCD-returns")).append("</b><blockquote>").append(ret).append("</blockquote>"); //NOI18N
491
}
492         if (thr.length() > 0) {
493             sb.append("<b>").append(NbBundle.getMessage(JavaCompletionDoc.class, "JCD-throws")).append("</b><blockquote>").append(thr).append("</blockquote>"); //NOI18N
494
}
495         if (since != null) {
496             sb.append("<b>").append(NbBundle.getMessage(JavaCompletionDoc.class, "JCD-since")).append("</b><blockquote>").append(since).append("</blockquote>"); //NOI18N
497
}
498         int length = see.length();
499         if (length > 0) {
500             sb.append("<b>").append(NbBundle.getMessage(JavaCompletionDoc.class, "JCD-see")).append("</b><blockquote>").append(see.delete(length - 2, length)).append("</blockquote>"); //NOI18N
501
}
502         return sb;
503     }
504     
505     private CharSequence JavaDoc getDeprecatedTag(ElementUtilities eu, Doc doc) {
506         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
507         for (Tag tag : doc.tags()) {
508             if (DEPRECATED_TAG.equals(tag.kind()))
509                 sb.append("<b>").append(NbBundle.getMessage(JavaCompletionDoc.class, "JCD-deprecated")).append("</b> <i>").append(tag.text()).append("</i></p><p>"); //NOI18N
510
}
511         return sb;
512     }
513     
514     private CharSequence JavaDoc inlineTags(ElementUtilities eu, Doc doc, Tag[] tags) {
515         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
516         for (Tag tag : tags) {
517             if (SEE_TAG.equals(tag.kind())) {
518                 SeeTag stag = (SeeTag)tag;
519                 ClassDoc refClass = stag.referencedClass();
520                 String JavaDoc memberName = stag.referencedMemberName();
521                 String JavaDoc label = stag.label();
522                 boolean plain = LINKPLAIN_TAG.equals(stag.name());
523                 if (memberName != null) {
524                     if (refClass != null) {
525                         createLink(sb, eu.elementFor(stag.referencedMember()), (plain ? "" : "<code>") + (label != null && label.length() > 0 ? label : (refClass.simpleTypeName() + "." + memberName)) + (plain ? "" : "</code>")); //NOI18N
526
} else {
527                         sb.append(stag.referencedClassName());
528                         sb.append('.'); //NOI18N
529
sb.append(memberName);
530                     }
531                 } else {
532                     if (refClass != null) {
533                         createLink(sb, eu.elementFor(refClass), (plain ? "" : "<code>") + (label != null && label.length() > 0 ? label : refClass.simpleTypeName()) + (plain ? "" : "</code>")); //NOI18N
534
} else {
535                         sb.append(stag.referencedClassName());
536                     }
537                 }
538             } else if (INHERIT_DOC_TAG.equals(tag.kind())) {
539                 if (doc.isMethod()) {
540                     MethodDoc mdoc = ((MethodDoc)doc).overriddenMethod();
541                     if (mdoc != null)
542                         sb.append(inlineTags(eu, mdoc, mdoc.inlineTags()));
543                 } else if (doc.isClass() || doc.isInterface()) {
544                     ClassDoc cdoc = ((ClassDoc)doc).superclass();
545                     if (cdoc != null)
546                         sb.append(inlineTags(eu, cdoc, cdoc.inlineTags()));
547                 }
548             } else if (CODE_TAG.equals(tag.kind())) {
549                 sb.append("<code>"); //NOI18N
550
sb.append(tag.text());
551                 sb.append("</code>"); //NOI18N
552
} else {
553                 sb.append(tag.text());
554             }
555         }
556         return sb;
557     }
558     
559     private CharSequence JavaDoc getFragment(Element e) {
560         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
561         if (!e.getKind().isClass() && !e.getKind().isInterface()) {
562             if (e.getKind() == ElementKind.CONSTRUCTOR) {
563                 sb.append(e.getEnclosingElement().getSimpleName());
564             } else {
565                 sb.append(e.getSimpleName());
566             }
567             if (e.getKind() == ElementKind.METHOD || e.getKind() == ElementKind.CONSTRUCTOR) {
568                 ExecutableElement ee = (ExecutableElement)e;
569                 sb.append('('); //NOI18N
570
for (Iterator JavaDoc<? extends VariableElement> it = ee.getParameters().iterator(); it.hasNext();) {
571                     VariableElement param = it.next();
572                     appendType(sb, param.asType(), ee.isVarArgs() && !it.hasNext());
573                     if (it.hasNext())
574                         sb.append(", ");
575                 }
576                 sb.append(')'); //NOI18N
577
}
578         }
579         return sb;
580     }
581     
582     private void appendType(StringBuilder JavaDoc sb, TypeMirror type, boolean varArg) {
583         switch (type.getKind()) {
584             case ARRAY:
585                 appendType(sb, ((ArrayType)type).getComponentType(), false);
586                 sb.append(varArg ? "..." : "[]"); //NOI18N
587
break;
588             case DECLARED:
589                 sb.append(((TypeElement)((DeclaredType)type).asElement()).getQualifiedName());
590                 break;
591             default:
592                 sb.append(type);
593         }
594     }
595
596     private void appendSpace(StringBuilder JavaDoc sb, int length) {
597         while (length-- >= 0)
598             sb.append(' '); //NOI18N
599
}
600     
601     private int appendType(ElementUtilities eu, StringBuilder JavaDoc sb, Type type, boolean varArg, boolean typeVar) {
602         int len = 0;
603         WildcardType wt = type.asWildcardType();
604         if (wt != null) {
605             sb.append('?'); //NOI18N
606
len++;
607             Type[] bounds = wt.extendsBounds();
608             if (bounds != null && bounds.length > 0) {
609                 sb.append(" extends "); //NOI18N
610
len += 9;
611                 len += appendType(eu, sb, bounds[0], false, false);
612             }
613             bounds = wt.superBounds();
614             if (bounds != null && bounds.length > 0) {
615                 sb.append(" super "); //NOI18N
616
len += 7;
617                 len += appendType(eu, sb, bounds[0], false, false);
618             }
619         } else {
620             TypeVariable tv = type.asTypeVariable();
621             if (tv != null) {
622                 len += createLink(sb, null, tv.simpleTypeName());
623                 Type[] bounds = tv.bounds();
624                 if (typeVar && bounds != null && bounds.length > 0) {
625                     sb.append(" extends "); //NOI18N
626
len += 9;
627                     for (int i = 0; i < bounds.length; i++) {
628                         len += appendType(eu, sb, bounds[i], false, false);
629                         if (i < bounds.length - 1) {
630                             sb.append(" & "); //NOI18N
631
len += 3;
632                         }
633                     }
634                 }
635             } else {
636                 String JavaDoc tName = type.simpleTypeName();
637                 ClassDoc cd = type.asClassDoc();
638                 if (cd != null && cd.isAnnotationType())
639                     tName = "@" + tName; //NOI18N
640
len += createLink(sb, eu.elementFor(type.asClassDoc()), tName);
641                 ParameterizedType pt = type.asParameterizedType();
642                 if (pt != null) {
643                     Type[] targs = pt.typeArguments();
644                     if (targs.length > 0) {
645                         sb.append("&lt;"); //NOI18N
646
for (int j = 0; j < targs.length; j++) {
647                             len += appendType(eu, sb, targs[j], false, false);
648                             if (j < targs.length - 1) {
649                                 sb.append(","); //NOI18N
650
len++;
651                             }
652                         }
653                         sb.append("&gt;"); //NOI18N
654
len += 2;
655                     }
656                 }
657             }
658         }
659         String JavaDoc dim = type.dimension();
660         if (dim.length() > 0) {
661             if (varArg)
662                 dim = dim.substring(2) + "..."; //NOI18N
663
sb.append(dim);
664             len += dim.length();
665         }
666         return len;
667     }
668     
669     private int createLink(StringBuilder JavaDoc sb, Element e, String JavaDoc text) {
670         if (e != null && e.asType().getKind() != TypeKind.ERROR) {
671             String JavaDoc link = "*" + linkCounter++; //NOI18N
672
links.put(link, ElementHandle.create(e));
673             sb.append("<a HREF='").append(link).append("'>"); //NOI18N
674
}
675         sb.append(text);
676         if (e != null)
677             sb.append("</a>"); //NOI18N
678
return text.length();
679     }
680 }
681
Popular Tags