1 21 22 package net.sourceforge.cobertura.reporting.html; 23 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.HashSet ; 27 28 public class JavaToHtml 29 { 30 31 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 private static final Collection javaKeywords; 48 private static final Collection javaPrimitiveLiterals; 49 private static final Collection javaPrimitiveTypes; 50 51 static 52 { 53 final String [] 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 javaPrimitiveTypesArray[] = { "boolean", "byte", "char", 65 "double", "float", "int", "long", "short", "void" }; 66 final String javaPrimitiveLiteralsArray[] = { "false", "null", "true" }; 67 68 javaKeywords = new HashSet (Arrays.asList(javaKeywordsArray)); 70 javaPrimitiveTypes = new HashSet (Arrays 71 .asList(javaPrimitiveTypesArray)); 72 javaPrimitiveLiterals = new HashSet (Arrays 73 .asList(javaPrimitiveLiteralsArray)); 74 } 75 76 private int state = State.DEFAULT; 77 78 private static String escapeEntity(final char character) 79 { 80 if (character == '&') 81 return "&"; 82 else if (character == '<') 83 return "<"; 84 else if (character == '>') 85 return ">"; 86 else if (character == '\t') 87 return " "; 88 else 89 return new Character (character).toString(); 90 } 91 92 99 public String process(final String text) 100 { 101 if (text == null) 102 throw new IllegalArgumentException ("\"text\" can not be null."); 103 104 StringBuffer ret = new StringBuffer (); 105 106 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 147 private String processLine(final String line) 148 { 149 if (line == null) 150 throw new IllegalArgumentException ("\"line\" can not be null."); 151 if ((line.indexOf('\n') != -1) || (line.indexOf('\r') != -1)) 152 throw new IllegalArgumentException ( 153 "\"line\" can not contain newline or carriage return characters."); 154 155 StringBuffer ret = new StringBuffer (); 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 ret.append(escapeEntity(line.charAt(currentIndex++))); 203 } 204 } 206 else if ((state == State.COMMENT_MULTI) 207 || (state == State.COMMENT_JAVADOC)) 208 { 209 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 } 231 else if (state == State.COMMENT_SINGLE) 232 { 233 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 } 245 else if (state == State.KEYWORD) 246 { 247 StringBuffer tmp = new StringBuffer (); 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 } 270 else if (state == State.IMPORT_NAME) 271 { 272 ret.append(escapeEntity(line.charAt(currentIndex++))); 273 state = State.DEFAULT; 274 } 276 else if (state == State.PACKAGE_NAME) 277 { 278 ret.append(escapeEntity(line.charAt(currentIndex++))); 279 state = State.DEFAULT; 280 } 282 else if (state == State.QUOTE_DOUBLE) 283 { 284 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 } 306 else if (state == State.QUOTE_SINGLE) 307 { 308 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 } 330 else 331 { 332 ret.append(escapeEntity(line.charAt(currentIndex++))); 334 } } 336 337 return ret.toString(); 338 } 339 340 346 public void reset() 347 { 348 state = State.DEFAULT; 349 } 350 351 } 352 | Popular Tags |