KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > http > servlets > jsp > JspParser


1 package com.quadcap.http.servlets.jsp;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.CharArrayWriter JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.Reader JavaDoc;
44
45 import org.xml.sax.AttributeList JavaDoc;
46 import org.xml.sax.DocumentHandler JavaDoc;
47 import org.xml.sax.DTDHandler JavaDoc;
48 import org.xml.sax.EntityResolver JavaDoc;
49 import org.xml.sax.ErrorHandler JavaDoc;
50 import org.xml.sax.InputSource JavaDoc;
51 import org.xml.sax.Parser JavaDoc;
52 import org.xml.sax.SAXException JavaDoc;
53
54 import org.xml.sax.helpers.AttributeListImpl JavaDoc;
55
56 import com.quadcap.util.collections.ArrayQueue;
57
58 /**
59  * JSP Parser class that fires SAX events.
60  *
61  * @author Stan Bailes
62  */

63 public class JspParser implements Parser JavaDoc {
64     InputSource JavaDoc in;
65     Reader JavaDoc r;
66     DocumentHandler JavaDoc docHandler = null;
67     DTDHandler JavaDoc dtdHandler = null;
68     EntityResolver JavaDoc entityResolver = null;
69     CharArrayWriter JavaDoc tag = new CharArrayWriter JavaDoc();
70     CharArrayWriter JavaDoc data = new CharArrayWriter JavaDoc();
71     AttributeListImpl JavaDoc attributes = new AttributeListImpl JavaDoc();
72     int tagState = 0;
73     String JavaDoc tagName = null;
74     JspHandler jspHandler = null;
75     String JavaDoc 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 JavaDoc in) throws SAXException JavaDoc,IOException JavaDoc {
87         this.in = in;
88         this.r = in.getCharacterStream();
89         tag.reset();
90         data.reset();
91         parse();
92     }
93
94     public void pushInputSource(InputSource JavaDoc 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 JavaDoc)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 JavaDoc s) {
113     }
114
115     public void setDocumentHandler(DocumentHandler JavaDoc dh) {
116         this.docHandler = dh;
117     }
118     
119     public void setDTDHandler(DTDHandler JavaDoc dh) {
120         this.dtdHandler = dh;
121     }
122
123     public void setEntityResolver(EntityResolver JavaDoc er) {
124     this.entityResolver = er;
125     }
126
127     public EntityResolver JavaDoc getEntityResolver() {
128     return entityResolver;
129     }
130
131     public void setErrorHandler(ErrorHandler JavaDoc er) {
132     }
133
134     public void setLocale(java.util.Locale JavaDoc locale) {
135     }
136     
137     public void parse() throws SAXException JavaDoc, IOException JavaDoc {
138         int state = 0;
139         int commentState = 0;
140         String JavaDoc attrName = null;
141         docHandler.startDocument();
142     docHandler.startElement("jsp:root", attributes);
143         while (state >= 0) {
144             int c = r.read();
145             //System.out.println("[" + ((char)c) + "] [" + state + "] <" + tag.toString() + ">");
146
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: // seen '<'
179
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: // seen '<%'
203
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: // in <% %>
226
if (c == '%') state = 7;
227                 else tag.write(c);
228                 break;
229             case 4: // seen <\
230
data.write('<');
231                 data.write(c);
232                 state = 0;
233                 break;
234             case 51: // collect directive name
235
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: // collect tag name
250
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: // collect attributes
285
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: // in <%, seen %
317
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: // seen </
329
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: // in <tag, seen /
346
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: // in attriblist, seen name=
358
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: // in <%@, seen %
368
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: // in attriblist, seen name="
378
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: // in attriblist, seen name='
388
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: // in attriblist, seen name=c
398
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: // in attriblist, seen name=dfdf/
421
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 JavaDoc {
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 JavaDoc {
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 JavaDoc {
493         docHandler.startElement("jsp:directive." + tagName, attributes);
494         docHandler.endElement("jsp:directive." + tagName);
495         attributes.clear();
496     }
497 }
498
Popular Tags