1 package com.quadcap.http.servlets.jsp; 2 3 40 41 import java.io.CharArrayWriter ; 42 import java.io.IOException ; 43 import java.io.Reader ; 44 45 import org.xml.sax.AttributeList ; 46 import org.xml.sax.DocumentHandler ; 47 import org.xml.sax.DTDHandler ; 48 import org.xml.sax.EntityResolver ; 49 import org.xml.sax.ErrorHandler ; 50 import org.xml.sax.InputSource ; 51 import org.xml.sax.Parser ; 52 import org.xml.sax.SAXException ; 53 54 import org.xml.sax.helpers.AttributeListImpl ; 55 56 import com.quadcap.util.collections.ArrayQueue; 57 58 63 public class JspParser implements Parser { 64 InputSource in; 65 Reader r; 66 DocumentHandler docHandler = null; 67 DTDHandler dtdHandler = null; 68 EntityResolver entityResolver = null; 69 CharArrayWriter tag = new CharArrayWriter (); 70 CharArrayWriter data = new CharArrayWriter (); 71 AttributeListImpl attributes = new AttributeListImpl (); 72 int tagState = 0; 73 String tagName = null; 74 JspHandler jspHandler = null; 75 String nonJspTag = null; 76 ArrayQueue inStack = null; 77 78 final static int TAG = 1; 79 final static int DIRECTIVE = 2; 80 final static int DECLARATION = 3; 81 final static int SCRIPTLET = 4; 82 final static int EXPRESSION = 5; 83 84 public JspParser() {} 85 86 public void parse(InputSource in) throws SAXException ,IOException { 87 this.in = in; 88 this.r = in.getCharacterStream(); 89 tag.reset(); 90 data.reset(); 91 parse(); 92 } 93 94 public void pushInputSource(InputSource in2) { 95 if (inStack == null) inStack = new ArrayQueue(); 96 inStack.push(in); 97 in = in2; 98 r = in.getCharacterStream(); 99 } 100 101 boolean popInputSource() { 102 if (inStack == null || inStack.size() == 0) return false; 103 in = (InputSource )inStack.pop(); 104 r = in.getCharacterStream(); 105 return true; 106 } 107 108 public void setJspHandler(JspHandler jspHandler) { 109 this.jspHandler = jspHandler; 110 } 111 112 public void parse(String s) { 113 } 114 115 public void setDocumentHandler(DocumentHandler dh) { 116 this.docHandler = dh; 117 } 118 119 public void setDTDHandler(DTDHandler dh) { 120 this.dtdHandler = dh; 121 } 122 123 public void setEntityResolver(EntityResolver er) { 124 this.entityResolver = er; 125 } 126 127 public EntityResolver getEntityResolver() { 128 return entityResolver; 129 } 130 131 public void setErrorHandler(ErrorHandler er) { 132 } 133 134 public void setLocale(java.util.Locale locale) { 135 } 136 137 public void parse() throws SAXException , IOException { 138 int state = 0; 139 int commentState = 0; 140 String attrName = null; 141 docHandler.startDocument(); 142 docHandler.startElement("jsp:root", attributes); 143 while (state >= 0) { 144 int c = r.read(); 145 if (c < 0) { 147 if (popInputSource()) continue; 148 state = -1; 149 break; 150 } 151 switch (commentState) { 152 case 0: 153 break; 154 case 1: 155 if (c == '-') commentState = 2; 156 break; 157 case 2: 158 if (c == '-') commentState = 3; 159 else commentState = 1; 160 break; 161 case 3: 162 if (c == '>') commentState = 0; 163 else if (c != '-') commentState = 1; 164 } 165 166 switch (state) { 167 case 0: 168 if (c == '<') { 169 if (data.size() > 0) { 170 docHandler.characters(data.toCharArray(), 0, data.size()); 171 data.reset(); 172 } 173 state = 1; 174 } else { 175 data.write(c); 176 } 177 break; 178 case 1: switch (c) { 180 case '%': 181 state = 2; 182 break; 183 case '!': 184 data.write('<'); 185 data.write('!'); 186 commentState = 1; 187 state = 0; 188 break; 189 case '\\': 190 state = 4; 191 break; 192 case '/': 193 state = 8; 194 break; 195 default: 196 tag.write(c); 197 tagState = TAG; 198 state = 5; 199 break; 200 } 201 break; 202 case 2: tag.reset(); 204 state = 3; 205 switch (c) { 206 case '@': 207 state = 51; 208 tagState = DIRECTIVE; 209 break; 210 case '!': 211 tagState = DECLARATION; 212 break; 213 case '=': 214 tagState = EXPRESSION; 215 break; 216 case '-': 217 state = 15; 218 break; 219 default: 220 tag.write(c); 221 tagState = SCRIPTLET; 222 break; 223 } 224 break; 225 case 3: if (c == '%') state = 7; 227 else tag.write(c); 228 break; 229 case 4: data.write('<'); 231 data.write(c); 232 state = 0; 233 break; 234 case 51: if (c != ' ') { 236 tag.write(c); 237 state = 52; 238 } 239 break; 240 case 52: 241 if (c == ' ') { 242 tagName = tag.toString(); 243 tag.reset(); 244 state = 6; 245 } else { 246 tag.write(c); 247 } 248 break; 249 case 5: switch (c) { 251 case ' ': 252 tagName = tag.toString(); 253 tag.reset(); 254 state = checkTag(6); 255 break; 256 case '/': 257 tagName = tag.toString(); 258 tag.reset(); 259 state = 9; 260 break; 261 case '>': 262 tagName = tag.toString(); 263 tag.reset(); 264 docHandler.startElement(tagName, attributes); 265 attributes.clear(); 266 state = 0; 267 break; 268 case '<': 269 tagName = tag.toString(); 270 tag.reset(); 271 if (checkTag(1) == 0) { 272 if (data.size() > 0) { 273 docHandler.characters(data.toCharArray(), 274 0, data.size()); 275 data.reset(); 276 } 277 state = 1; 278 } 279 break; 280 default: 281 tag.write(c); 282 } 283 break; 284 case 6: switch (c) { 286 case ' ': case '\n': case '\r': case '\t': 287 break; 288 case '/': 289 if (tagState == TAG) { 290 state = 9; 291 } else { 292 tag.write(c); 293 } 294 break; 295 case '%': 296 if (tagState != TAG) { 297 state = 11; 298 } else { 299 tag.write(c); 300 } 301 break; 302 case '>': 303 docHandler.startElement(tagName, attributes); 304 attributes.clear(); 305 state = 0; 306 break; 307 case '=': 308 attrName = tag.toString(); 309 tag.reset(); 310 state = 10; 311 break; 312 default: 313 tag.write(c); 314 } 315 break; 316 case 7: if (c == '>') { 318 doTag(); 319 state = 0; 320 } else { 321 tag.write('%'); 322 if (c != '%') { 323 tag.write(c); 324 state = 3; 325 } 326 } 327 break; 328 case 8: if (c == '>') { 330 tagName = tag.toString(); 331 tag.reset(); 332 if (nonJspTag != null && tagName.equals(nonJspTag)) { 333 nonJspTag = null; 334 data.write("</"); 335 data.write(tagName); 336 data.write('>'); 337 } else { 338 docHandler.endElement(tagName); 339 } 340 state = 0; 341 } else { 342 tag.write(c); 343 } 344 break; 345 case 9: if (c == '>') { 347 docHandler.startElement(tagName, attributes); 348 attributes.clear(); 349 docHandler.endElement(tagName); 350 state = 0; 351 } else { 352 tag.write('/'); 353 tag.write(c); 354 state = 6; 355 } 356 break; 357 case 10: if (c == '"') { 359 state = 12; 360 } else if (c == '\'') { 361 state = 121; 362 } else { 363 tag.write(c); 364 state = 13; 365 } 366 break; 367 case 11: if (c == '>') { 369 doDirective(); 370 state = 0; 371 } else { 372 tag.write('%'); 373 tag.write(c); 374 state = 6; 375 } 376 break; 377 case 12: if (c == '"') { 379 attributes.addAttribute(attrName, "string", 380 tag.toString()); 381 tag.reset(); 382 state = 6; 383 } else { 384 tag.write(c); 385 } 386 break; 387 case 121: if (c == '\'') { 389 attributes.addAttribute(attrName, "string", 390 tag.toString()); 391 tag.reset(); 392 state = 6; 393 } else { 394 tag.write(c); 395 } 396 break; 397 case 13: switch (c) { 399 case ' ': 400 attributes.addAttribute(attrName, "string", 401 tag.toString()); 402 tag.reset(); 403 state = 6; 404 break; 405 case '/': 406 state = 14; 407 break; 408 case '>': 409 attributes.addAttribute(attrName, "string", 410 tag.toString()); 411 tag.reset(); 412 docHandler.startElement(tagName, attributes); 413 attributes.clear(); 414 state = 0; 415 break; 416 default: 417 tag.write(c); 418 } 419 break; 420 case 14: if (c == '>') { 422 attributes.addAttribute(attrName, "string", 423 tag.toString()); 424 tag.reset(); 425 docHandler.startElement(tagName, attributes); 426 attributes.clear(); 427 state = 0; 428 } else { 429 tag.write('/'); 430 if (c != '/') { 431 tag.write(c); 432 state = 13; 433 } 434 } 435 break; 436 case 15: 437 if (c == '-') state = 16; 438 break; 439 case 16: 440 if (c == '-') state = 17; 441 else state = 15; 442 break; 443 case 17: 444 if (c == '>') state = 0; 445 else if (c != '-') state = 15; 446 break; 447 } 448 } 449 docHandler.endElement("jsp:root"); 450 } 451 452 public int checkTag(int validState) throws IOException { 453 if (jspHandler.isValidTag(tagName)) { 454 return validState; 455 } else { 456 nonJspTag = tagName; 457 data.write('<'); 458 data.write(tagName); 459 data.write(' '); 460 return 0; 461 } 462 } 463 464 public void doTag() throws SAXException { 465 switch (tagState) { 466 case TAG: 467 break; 468 case EXPRESSION: 469 docHandler.startElement("jsp:expression", attributes); 470 docHandler.characters(tag.toCharArray(), 0, tag.size()); 471 docHandler.endElement("jsp:expression"); 472 tag.reset(); 473 attributes.clear(); 474 break; 475 case DECLARATION: 476 docHandler.startElement("jsp:decl", attributes); 477 docHandler.characters(tag.toCharArray(), 0, tag.size()); 478 docHandler.endElement("jsp:decl"); 479 tag.reset(); 480 attributes.clear(); 481 break; 482 case SCRIPTLET: 483 docHandler.startElement("jsp:scriptlet", attributes); 484 docHandler.characters(tag.toCharArray(), 0, tag.size()); 485 docHandler.endElement("jsp:scriptlet"); 486 tag.reset(); 487 attributes.clear(); 488 break; 489 } 490 } 491 492 public void doDirective() throws SAXException { 493 docHandler.startElement("jsp:directive." + tagName, attributes); 494 docHandler.endElement("jsp:directive." + tagName); 495 attributes.clear(); 496 } 497 } 498 | Popular Tags |