]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/text/javadoc/JavaDoc2HTMLTextReader.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / text / javadoc / JavaDoc2HTMLTextReader.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Brock Janiczak (brockj_eclipse@ihug.com.au) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=20644
11 * Brock Janiczak (brockj_eclipse@ihug.com.au) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=83607
12 * Benjamin Muskalla <b.muskalla@gmx.net> - [navigation][hovering] Javadoc view cannot find URL with anchor - https://bugs.eclipse.org/bugs/show_bug.cgi?id=70870
13 *******************************************************************************/
14package org.eclipse.jdt.internal.ui.text.javadoc;
15
16import java.io.IOException;
17import java.io.Reader;
18import java.util.ArrayList;
19import java.util.Iterator;
20import java.util.List;
21
22import org.eclipse.jface.internal.text.html.HTMLPrinter;
23import org.eclipse.jface.internal.text.html.SubstitutionTextReader;
24
25import org.eclipse.jdt.core.dom.TagElement;
26
27
28/**
29 * Processes JavaDoc tags.
30 */
31public class JavaDoc2HTMLTextReader extends SubstitutionTextReader {
32
33
34 static class Pair {
35 String fTag;
36 String fContent;
37
38 Pair(String tag, String content) {
39 fTag= tag;
40 fContent= content;
41 }
42
43 public void generated_5851077662602872979(StringBuffer buffer, JavaDoc2HTMLTextReader javadoc2htmltextreader) {
44 if (fTag != null)
45 buffer.append(fTag);
46 buffer.append("</dt>"); //$NON-NLS-1$
47 buffer.append("<dd>"); //$NON-NLS-1$
48 if (fContent != null)
49 buffer.append(fContent);
50 }
51 }
52
53 private List<String> fParameters;
54 private String fReturn;
55 private List<String> fExceptions;
56 private List<String> fAuthors;
57 private List<String> fSees;
58 private List<String> fSince;
59 private List<Pair> fRest; // list of Pair objects
60
61 public JavaDoc2HTMLTextReader(Reader reader) {
62 super(reader);
63 setSkipWhitespace(false);
64 }
65
66 private int getTag(StringBuffer buffer) throws IOException {
67 int c= nextChar();
68 while (c == '.' || c != -1 && Character.isLetter((char) c)) {
69 buffer.append((char) c);
70 c= nextChar();
71 }
72 return c;
73 }
74
75 private int getContent(StringBuffer buffer, char stopChar) throws IOException {
76 int c= nextChar();
77 while (c != -1 && c != stopChar) {
78 buffer.append((char) c);
79 c= nextChar();
80 }
81 return c;
82 }
83
84 private int getContentUntilNextTag(StringBuffer buffer) throws IOException {
85 int c= nextChar();
86 boolean blockStartRead= false;
87 while (c != -1) {
88 if (c == '@') {
89 int index= buffer.length();
90 while (--index >= 0 && Character.isWhitespace(buffer.charAt(index))) {
91 switch (buffer.charAt(index)) {
92 case '\n':
93 case '\r':
94 return c;
95 }
96 if (index <= 0) {
97 return c;
98 }
99 }
100 }
101 if (blockStartRead) {
102 buffer.append(processBlockTag());
103 blockStartRead= false;
104 } else {
105 buffer.append((char) c);
106 }
107
108 c= nextChar();
109 blockStartRead= c == '{';
110 }
111 return c;
112 }
113
114 private String substituteQualification(String qualification) {
115 String result;
116 if (qualification.indexOf("<a") == -1) { //$NON-NLS-1$
117 // No tag at all, use smart way
118 result= qualification.replace('#', '.');
119 } else {
120 // Handle tags
121 int length= qualification.length();
122 result= qualification;
123 boolean insideTag= false;
124 for (int i= 0; i < length; i++) {
125 char charAt= result.charAt(i);
126 if (charAt == '<' && result.charAt(i + 1) == 'a')
127 insideTag= true;
128 if (charAt == '>')
129 insideTag= false;
130 if (charAt == '#' && !insideTag)
131 result= result.substring(0, i) + "." + result.substring(i + 1); //$NON-NLS-1$
132 }
133 }
134
135 if (result.startsWith(".")) //$NON-NLS-1$
136 result= result.substring(1);
137 return result;
138 }
139
140 private void printDefinitions(StringBuffer buffer, List<String> list, boolean firstword) {
141 Iterator<String> e= list.iterator();
142 while (e.hasNext()) {
143 String s= e.next();
144 buffer.append("<dd>"); //$NON-NLS-1$
145 if (!firstword)
146 buffer.append(s);
147 else {
148 buffer.append("<b>"); //$NON-NLS-1$
149
150 int i= getParamEndOffset(s);
151 if (i <= s.length()) {
152 buffer.append(HTMLPrinter.convertToHTMLContent(s.substring(0, i)));
153 buffer.append("</b>"); //$NON-NLS-1$
154 buffer.append(s.substring(i));
155 } else {
156 buffer.append("</b>"); //$NON-NLS-1$
157 }
158 }
159 buffer.append("</dd>"); //$NON-NLS-1$
160 }
161 }
162
163 private int getParamEndOffset(String s) {
164 int i= 0;
165 final int length= s.length();
166 // \s*
167 while (i < length && Character.isWhitespace(s.charAt(i)))
168 ++i;
169 if (i < length && s.charAt(i) == '<') {
170 // generic type parameter
171 // read <\s*\w*\s*>
172 while (i < length && Character.isWhitespace(s.charAt(i)))
173 ++i;
174 while (i < length && Character.isJavaIdentifierPart(s.charAt(i)))
175 ++i;
176 while (i < length && s.charAt(i) != '>')
177 ++i;
178 } else {
179 // simply read an identifier
180 while (i < length && Character.isJavaIdentifierPart(s.charAt(i)))
181 ++i;
182 }
183
184 return i;
185 }
186
187 private void print(StringBuffer buffer, String tag, List<String> elements, boolean firstword) {
188 if ( !elements.isEmpty()) {
189 buffer.append("<dt>"); //$NON-NLS-1$
190 buffer.append(tag);
191 buffer.append("</dt>"); //$NON-NLS-1$
192 printDefinitions(buffer, elements, firstword);
193 }
194 }
195
196 private void print(StringBuffer buffer, String tag, String content) {
197 if (content != null) {
198 buffer.append("<dt>"); //$NON-NLS-1$
199 buffer.append(tag);
200 buffer.append("</dt>"); //$NON-NLS-1$
201 buffer.append("<dd>"); //$NON-NLS-1$
202 buffer.append(content);
203 buffer.append("</dd>"); //$NON-NLS-1$
204 }
205 }
206
207 private void printRest(StringBuffer buffer) {
208 if ( !fRest.isEmpty()) {
209 Iterator<Pair> e= fRest.iterator();
210 while (e.hasNext()) {
211 Pair p= e.next();
212 buffer.append("<dt>"); //$NON-NLS-1$
213 p.generated_5851077662602872979(buffer, this);
214 buffer.append("</dd>"); //$NON-NLS-1$
215 }
216 }
217 }
218
219 private String printSimpleTag() {
220 StringBuffer buffer= new StringBuffer();
221 buffer.append("<dl>"); //$NON-NLS-1$
222 print(buffer, JavaDocMessages.JavaDoc2HTMLTextReader_see_section, fSees, false);
223 print(buffer, JavaDocMessages.JavaDoc2HTMLTextReader_parameters_section, fParameters, true);
224 print(buffer, JavaDocMessages.JavaDoc2HTMLTextReader_returns_section, fReturn);
225 print(buffer, JavaDocMessages.JavaDoc2HTMLTextReader_throws_section, fExceptions, false);
226 print(buffer, JavaDocMessages.JavaDoc2HTMLTextReader_author_section, fAuthors, false);
227 print(buffer, JavaDocMessages.JavaDoc2HTMLTextReader_since_section, fSince, false);
228 printRest(buffer);
229 buffer.append("</dl>"); //$NON-NLS-1$
230
231 return buffer.toString();
232 }
233
234 private void handleTag(String tag, String tagContent) {
235
236 tagContent= tagContent.trim();
237
238 if (TagElement.TAG_PARAM.equals(tag))
239 fParameters.add(tagContent);
240 else if (TagElement.TAG_RETURN.equals(tag))
241 fReturn= tagContent;
242 else if (TagElement.TAG_EXCEPTION.equals(tag))
243 fExceptions.add(tagContent);
244 else if (TagElement.TAG_THROWS.equals(tag))
245 fExceptions.add(tagContent);
246 else if (TagElement.TAG_AUTHOR.equals(tag))
247 fAuthors.add(substituteQualification(tagContent));
248 else if (TagElement.TAG_SEE.equals(tag))
249 fSees.add(substituteQualification(tagContent));
250 else if (TagElement.TAG_SINCE.equals(tag))
251 fSince.add(substituteQualification(tagContent));
252 else if (tagContent != null)
253 fRest.add(new Pair(tag, tagContent));
254 }
255
256 /*
257 * A '@' has been read. Process a javadoc tag
258 */
259 private String processSimpleTag() throws IOException {
260
261 fParameters= new ArrayList<String>();
262 fExceptions= new ArrayList<String>();
263 fAuthors= new ArrayList<String>();
264 fSees= new ArrayList<String>();
265 fSince= new ArrayList<String>();
266 fRest= new ArrayList<Pair>();
267
268 StringBuffer buffer= new StringBuffer();
269 int c= '@';
270 while (c != -1) {
271
272 buffer.setLength(0);
273 buffer.append((char) c);
274 c= getTag(buffer);
275 String tag= buffer.toString();
276
277 buffer.setLength(0);
278 if (c != -1) {
279 c= getContentUntilNextTag(buffer);
280 }
281
282 handleTag(tag, buffer.toString());
283 }
284
285 return printSimpleTag();
286 }
287
288 private String printBlockTag(String tag, String tagContent) {
289
290 if (TagElement.TAG_LINK.equals(tag) || TagElement.TAG_LINKPLAIN.equals(tag)) {
291
292 char[] contentChars= tagContent.toCharArray();
293 boolean inParentheses= false;
294 int labelStart= 0;
295
296 for (int i= 0; i < contentChars.length; i++) {
297 char nextChar= contentChars[i];
298
299 // tagContent always has a leading space
300 if (i == 0 && Character.isWhitespace(nextChar)) {
301 labelStart= 1;
302 continue;
303 }
304
305 if (nextChar == '(') {
306 inParentheses= true;
307 continue;
308 }
309
310 if (nextChar == ')') {
311 inParentheses= false;
312 continue;
313 }
314
315 // Stop at first whitespace that is not in parentheses
316 if (!inParentheses && Character.isWhitespace(nextChar)) {
317 labelStart= i+1;
318 break;
319 }
320 }
321 if (TagElement.TAG_LINK.equals(tag))
322 return "<code>" + substituteQualification(tagContent.substring(labelStart)) + "</code>"; //$NON-NLS-1$//$NON-NLS-2$
323 else
324 return substituteQualification(tagContent.substring(labelStart));
325
326 } else if (TagElement.TAG_LITERAL.equals(tag)) {
327 return printLiteral(tagContent);
328
329 } else if (TagElement.TAG_CODE.equals(tag)) {
330 return "<code>" + printLiteral(tagContent) + "</code>"; //$NON-NLS-1$//$NON-NLS-2$
331 }
332
333 // If something went wrong at least replace the {} with the content
334 return substituteQualification(tagContent);
335 }
336
337 private String printLiteral(String tagContent) {
338 int contentStart= 0;
339 for (int i= 0; i < tagContent.length(); i++) {
340 if (! Character.isWhitespace(tagContent.charAt(i))) {
341 contentStart= i;
342 break;
343 }
344 }
345 return HTMLPrinter.convertToHTMLContent(tagContent.substring(contentStart));
346 }
347
348 /*
349 * A '{' has been read. Process a block tag
350 */
351 private String processBlockTag() throws IOException {
352
353 int c= nextChar();
354
355 if (c != '@') {
356 StringBuffer buffer= new StringBuffer();
357 buffer.append('{');
358 buffer.append((char) c);
359 return buffer.toString();
360 }
361
362 StringBuffer buffer= new StringBuffer();
363 if (c != -1) {
364
365 buffer.setLength(0);
366 buffer.append((char) c);
367
368 c= getTag(buffer);
369 String tag= buffer.toString();
370
371 buffer.setLength(0);
372 if (c != -1 && c != '}') {
373 buffer.append((char) c);
374 c= getContent(buffer, '}');
375 }
376
377 return printBlockTag(tag, buffer.toString());
378 }
379
380 return null;
381 }
382
383 /*
384 * @see SubstitutionTextReaderr#computeSubstitution(int)
385 */
386 @Override
387 protected String computeSubstitution(int c) throws IOException {
388 if (c == '@' && fWasWhiteSpace)
389 return processSimpleTag();
390
391 if (c == '{')
392 return processBlockTag();
393
394 return null;
395 }
396}