KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cobertura > reporting > html > JavaToHtml


1 /*
2  * Cobertura - http://cobertura.sourceforge.net/
3  *
4  * Copyright (C) 2005 Mark Doliner
5  *
6  * Cobertura is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2 of the License,
9  * or (at your option) any later version.
10  *
11  * Cobertura is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Cobertura; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  */

21
22 package net.sourceforge.cobertura.reporting.html;
23
24 import java.util.Arrays JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.HashSet JavaDoc;
27
28 public class JavaToHtml
29 {
30
31     // Could use a J2SE 5.0 enum instead of this.
32
public abstract static class State
33     {
34         public final static int COMMENT_JAVADOC = 0;
35         public final static int COMMENT_MULTI = 1;
36         public final static int COMMENT_SINGLE = 2;
37         public final static int DEFAULT = 3;
38         public final static int KEYWORD = 4;
39         public final static int IMPORT_NAME = 5;
40         public final static int PACKAGE_NAME = 6;
41         public final static int QUOTE_DOUBLE = 8;
42         public final static int QUOTE_SINGLE = 9;
43     }
44
45     // TODO: Set a style for JavaDoc tags
46
//private static final Collection javaJavaDocTags;
47
private static final Collection JavaDoc javaKeywords;
48     private static final Collection JavaDoc javaPrimitiveLiterals;
49     private static final Collection JavaDoc javaPrimitiveTypes;
50
51     static
52     {
53         // TODO: Probably need to add anything new in J2SE 5.0
54
//final String javaJavaDocTagsArray[] = { "see", "author", "version", "param", "return", "exception",
55
// "deprecated", "throws", "link", "since", "serial", "serialField", "serialData", "beaninfo" };
56
final String JavaDoc[] javaKeywordsArray = { "abstract", "assert", "break",
57                 "case", "catch", "class", "const", "continue", "default",
58                 "do", "else", "extends", "final", "finally", "for", "goto",
59                 "if", "interface", "implements", "import", "instanceof",
60                 "native", "new", "package", "private", "protected", "public",
61                 "return", "static", "strictfp", "super", "switch",
62                 "synchronized", "this", "throw", "throws", "transient",
63                 "try", "volatile", "while" };
64         final String JavaDoc javaPrimitiveTypesArray[] = { "boolean", "byte", "char",
65                 "double", "float", "int", "long", "short", "void" };
66         final String JavaDoc javaPrimitiveLiteralsArray[] = { "false", "null", "true" };
67
68         //javaJavaDocTags = new HashSet(Arrays.asList(javaJavaDocTagsArray));
69
javaKeywords = new HashSet JavaDoc(Arrays.asList(javaKeywordsArray));
70         javaPrimitiveTypes = new HashSet JavaDoc(Arrays
71                 .asList(javaPrimitiveTypesArray));
72         javaPrimitiveLiterals = new HashSet JavaDoc(Arrays
73                 .asList(javaPrimitiveLiteralsArray));
74     }
75
76     private int state = State.DEFAULT;
77
78     private static String JavaDoc escapeEntity(final char character)
79     {
80         if (character == '&')
81             return "&";
82         else if (character == '<')
83             return "&lt;";
84         else if (character == '>')
85             return "&gt;";
86         else if (character == '\t')
87             return " ";
88         else
89             return new Character JavaDoc(character).toString();
90     }
91
92     /**
93      * Add HTML colorization to a block of Java code.
94      *
95      * @param text The block of Java code.
96      * @return The same block of Java code with added span tags.
97      * Newlines are preserved.
98      */

99     public String JavaDoc process(final String JavaDoc text)
100     {
101         if (text == null)
102             throw new IllegalArgumentException JavaDoc("\"text\" can not be null.");
103
104         StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
105
106         // This look is really complicated because it preserves all
107
// combinations of \r, \n, \r\n, and \n\r
108
int begin, end, nextCR;
109         begin = 0;
110         end = text.indexOf('\n', begin);
111         nextCR = text.indexOf('\r', begin);
112         if ((nextCR != -1) && ((end == -1) || (nextCR < end)))
113             end = nextCR;
114         while (end != -1)
115         {
116             ret.append(processLine(text.substring(begin, end)) + "<br/>");
117
118             if ((end + 1 < text.length())
119                     && ((text.charAt(end + 1) == '\n') || (text
120                             .charAt(end + 1) == '\r')))
121             {
122                 ret.append(text.substring(end, end + 1));
123                 begin = end + 2;
124             }
125             else
126             {
127                 ret.append(text.charAt(end));
128                 begin = end + 1;
129             }
130
131             end = text.indexOf('\n', begin);
132             nextCR = text.indexOf('\r', begin);
133             if ((nextCR != -1) && ((end == -1) || (nextCR < end)))
134                 end = nextCR;
135         }
136         ret.append(processLine(text.substring(begin)));
137
138         return ret.toString();
139     }
140
141     /**
142      * Add HTML colorization to a single line of Java code.
143      *
144      * @param line One line of Java code.
145      * @return The same line of Java code with added span tags.
146      */

147     private String JavaDoc processLine(final String JavaDoc line)
148     {
149         if (line == null)
150             throw new IllegalArgumentException JavaDoc("\"line\" can not be null.");
151         if ((line.indexOf('\n') != -1) || (line.indexOf('\r') != -1))
152             throw new IllegalArgumentException JavaDoc(
153                     "\"line\" can not contain newline or carriage return characters.");
154
155         StringBuffer JavaDoc ret = new StringBuffer JavaDoc();
156         int currentIndex = 0;
157
158         while (currentIndex != line.length())
159         {
160             if (state == State.DEFAULT)
161             {
162                 if ((currentIndex + 2 < line.length())
163                         && line.substring(currentIndex, currentIndex + 3)
164                                 .equals("/**"))
165                 {
166                     state = State.COMMENT_JAVADOC;
167
168                 }
169                 else if ((currentIndex + 1 < line.length())
170                         && line.substring(currentIndex, currentIndex + 2)
171                                 .equals("/*"))
172                 {
173                     state = State.COMMENT_MULTI;
174
175                 }
176                 else if ((currentIndex + 1 < line.length())
177                         && (line.substring(currentIndex, currentIndex + 2)
178                                 .equals("//")))
179                 {
180                     state = State.COMMENT_SINGLE;
181
182                 }
183                 else if (Character.isJavaIdentifierStart(line
184                         .charAt(currentIndex)))
185                 {
186                     state = State.KEYWORD;
187
188                 }
189                 else if (line.charAt(currentIndex) == '\'')
190                 {
191                     state = State.QUOTE_SINGLE;
192
193                 }
194                 else if (line.charAt(currentIndex) == '"')
195                 {
196                     state = State.QUOTE_DOUBLE;
197
198                 }
199                 else
200                 {
201                     // Default: No highlighting.
202
ret.append(escapeEntity(line.charAt(currentIndex++)));
203                 }
204             } // End of State.DEFAULT
205

206             else if ((state == State.COMMENT_MULTI)
207                     || (state == State.COMMENT_JAVADOC))
208             {
209                 // Print everything from the current character until the
210
// closing */ No exceptions.
211
ret.append("<span class=\"comment\">");
212                 while ((currentIndex != line.length())
213                         && !((currentIndex + 1 < line.length()) && (line
214                                 .substring(currentIndex, currentIndex + 2)
215                                 .equals("*/"))))
216                 {
217                     ret.append(escapeEntity(line.charAt(currentIndex++)));
218                 }
219                 if (currentIndex == line.length())
220                 {
221                     ret.append("</span>");
222                 }
223                 else
224                 {
225                     ret.append("*/</span>");
226                     state = State.DEFAULT;
227                     currentIndex += 2;
228                 }
229             } // End of State.COMMENT_MULTI
230

231             else if (state == State.COMMENT_SINGLE)
232             {
233                 // Print everything from the current character until the
234
// end of the line
235
ret.append("<span class=\"comment\">");
236                 while (currentIndex != line.length())
237                 {
238                     ret.append(escapeEntity(line.charAt(currentIndex++)));
239                 }
240                 ret.append("</span>");
241                 state = State.DEFAULT;
242
243             } // End of State.COMMENT_SINGLE
244

245             else if (state == State.KEYWORD)
246             {
247                 StringBuffer JavaDoc tmp = new StringBuffer JavaDoc();
248                 do
249                 {
250                     tmp.append(line.charAt(currentIndex++));
251                 } while ((currentIndex != line.length())
252                         && (Character.isJavaIdentifierPart(line
253                                 .charAt(currentIndex))));
254                 if (javaKeywords.contains(tmp.toString()))
255                     ret.append("<span class=\"keyword\">" + tmp + "</span>");
256                 else if (javaPrimitiveLiterals.contains(tmp.toString()))
257                     ret.append("<span class=\"keyword\">" + tmp + "</span>");
258                 else if (javaPrimitiveTypes.contains(tmp.toString()))
259                     ret.append("<span class=\"keyword\">" + tmp + "</span>");
260                 else
261                     ret.append(tmp);
262                 if (tmp.toString().equals("import"))
263                     state = State.IMPORT_NAME;
264                 else if (tmp.toString().equals("package"))
265                     state = State.PACKAGE_NAME;
266                 else
267                     state = State.DEFAULT;
268             } // End of State.KEYWORD
269

270             else if (state == State.IMPORT_NAME)
271             {
272                 ret.append(escapeEntity(line.charAt(currentIndex++)));
273                 state = State.DEFAULT;
274             } // End of State.IMPORT_NAME
275

276             else if (state == State.PACKAGE_NAME)
277             {
278                 ret.append(escapeEntity(line.charAt(currentIndex++)));
279                 state = State.DEFAULT;
280             } // End of State.PACKAGE_NAME
281

282             else if (state == State.QUOTE_DOUBLE)
283             {
284                 // Print everything from the current character until the
285
// closing ", checking for \"
286
ret.append("<span class=\"string\">");
287                 do
288                 {
289                     ret.append(escapeEntity(line.charAt(currentIndex++)));
290                 } while ((currentIndex != line.length())
291                         && (!(line.charAt(currentIndex) == '"') || ((line
292                                 .charAt(currentIndex - 1) == '\\') && (line
293                                 .charAt(currentIndex - 2) != '\\'))));
294                 if (currentIndex == line.length())
295                 {
296                     ret.append("</span>");
297                 }
298                 else
299                 {
300                     ret.append("\"</span>");
301                     state = State.DEFAULT;
302                     currentIndex++;
303                 }
304             } // End of State.QUOTE_DOUBLE
305

306             else if (state == State.QUOTE_SINGLE)
307             {
308                 // Print everything from the current character until the
309
// closing ', checking for \'
310
ret.append("<span class=\"string\">");
311                 do
312                 {
313                     ret.append(escapeEntity(line.charAt(currentIndex++)));
314                 } while ((currentIndex != line.length())
315                         && (!(line.charAt(currentIndex) == '\'') || ((line
316                                 .charAt(currentIndex - 1) == '\\') && (line
317                                 .charAt(currentIndex - 2) != '\\'))));
318                 if (currentIndex == line.length())
319                 {
320                     ret.append("</span>");
321                 }
322                 else
323                 {
324                     ret.append("\'</span>");
325                     state = State.DEFAULT;
326                     currentIndex++;
327                 }
328             } // End of State.QUOTE_SINGLE
329

330             else
331             {
332                 // Default: No highlighting.
333
ret.append(escapeEntity(line.charAt(currentIndex++)));
334             } // End of unknown state
335
}
336
337         return ret.toString();
338     }
339
340     /**
341      * Reset the state of this Java parser. Call this if you have
342      * been parsing one Java file and you want to begin parsing
343      * another Java file.
344      *
345      */

346     public void reset()
347     {
348         state = State.DEFAULT;
349     }
350
351 }
352
Popular Tags