KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > finalist > jag > template > parser > JagParser


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

17
18 package com.finalist.jag.template.parser;
19
20 /* Generated by Together */
21
22 /**
23  * Class JagParser
24  *
25  * Generates a tree structure for a jag template file.
26  *
27  * @author Wendel D. de Witte
28  * @version %I%, %G%
29  */

30 public class JagParser implements JagParserConstants {
31
32    /** Field input */
33    private CharBuffer input = null;
34
35    /** Field lnkJagBlockCollection */
36    private JagBlockCollection lnkJagBlockCollection = null;
37
38    /** Field tagDefBegin */
39    private String JavaDoc tagDefBegin = null;
40
41    /** Field tagDefEnd */
42    private String JavaDoc tagDefEnd = null;
43
44    /** Field tagDefClose */
45    private String JavaDoc tagDefClose = null;
46
47    /** Field tagDefClose */
48    private String JavaDoc tagDefBodyClose = null;
49
50    /** Field currentBlock */
51    private JagBlockImpl currentBlock = null;
52
53
54    /**
55     * Constructor JagParser
56     *
57     *
58     */

59    public JagParser() {
60    }
61
62
63    /**
64     * Method process
65     *
66     *
67     * @param input
68     *
69     * @return
70     *
71     */

72    public boolean process(CharBuffer input) {
73       // Initialize the tag definitions
74
tagDefBegin = getTokenString(TAGDEF_BEGIN);
75       tagDefEnd = getTokenString(TAGDEF_END);
76       tagDefClose = getTokenString(TAGDEF_CLOSE) + tagDefEnd;
77       tagDefBodyClose = getTokenString(TAGDEF_BEGIN) + getTokenString(TAGDEF_CLOSE);
78       lnkJagBlockCollection = new JagBlockCollection();
79       currentBlock = lnkJagBlockCollection;
80       this.input = input;
81
82       // Buffer for holding the text between the tags.
83
StringBuffer JavaDoc text = new StringBuffer JavaDoc();
84
85       try {
86          // todo : header exception when they appear after a tag definition.
87
boolean expandBuffer = true;
88          while (EOF_CHAR != input.LA(1)) {
89             // process header.
90
if (isHeaderDefinition()) {
91                expandBuffer = !processHeader();
92                text = new StringBuffer JavaDoc();
93             } else if (isCommentDefinition()) {
94                consumeComment();
95             }
96             // process tag
97
else if (isTagDefinition()) {
98                insertTextBlock(currentBlock, new String JavaDoc(text));
99                text = new StringBuffer JavaDoc();
100                // ignore the false return value, should be handle
101
// by the processor of the tree structure.
102
expandBuffer = !processTag();
103             }
104             // expand text buffer
105
if (expandBuffer) {
106                text.append(input.LA(1));
107                input.consume();
108             }
109             expandBuffer = true;
110          }
111       } catch (Exception JavaDoc e) {
112       }
113       // Insert the remaining textBlock.
114
insertTextBlock(currentBlock, new String JavaDoc(text));
115       return false;
116    }
117
118
119    /**
120     * Method process
121     *
122     * @return
123     */

124    public boolean processTagBody() throws CharStreamException, JagParserException {
125       StringBuffer JavaDoc text = new StringBuffer JavaDoc();
126       boolean expandBuffer = true;
127       while (EOF_CHAR != input.LA(1)) {
128          // process end of tagbody.
129
if (isTagDefBodyClose()) {
130             insertTextBlock(currentBlock, new String JavaDoc(text));
131             text = new StringBuffer JavaDoc();
132             return true;
133          } else if (isCommentDefinition()) {
134             consumeComment();
135          }
136          // process inner tag
137
else if (isTagDefinition()) {
138             insertTextBlock(currentBlock, new String JavaDoc(text));
139             text = new StringBuffer JavaDoc();
140             expandBuffer = !processTag();
141          }
142
143          // expand text block
144
if (expandBuffer) {
145             text.append(input.LA(1));
146             input.consume();
147          }
148          expandBuffer = true;
149       }
150       // Insert the remaining textBlock.
151
insertTextBlock(currentBlock, new String JavaDoc(text));
152       return false;
153    }
154
155
156    /**
157     * Method insertTextBlock
158     *
159     * Inserts a textblock. Invalid textblocks are ignored.
160     * A textblock is invalid if the first character is an eol symbol
161     * or the string is empty.
162     *
163     * @param parent
164     * @param text
165     *
166     */

167    protected void insertTextBlock(JagBlock parent, String JavaDoc text) {
168       if (text.length() > 0 && text.charAt(0) != EOF_CHAR) {
169          JagBlockImpl blockChild = new JagBlockImpl();
170          blockChild.initialize(TEXT, new String JavaDoc(text));
171          parent.addChild(blockChild);
172       }
173    }
174
175
176    /**
177     * Method processHeader
178     *
179     *
180     * @return
181     *
182     */

183    protected boolean processHeader() {
184       int mark = input.mark();
185       try {
186          match(HEADERDEF_BEGIN);
187          // start
188
JagBlockImpl block = new JagBlockImpl();
189          block.initialize(HEADERDEF_BEGIN, "HEADERDEF_BEGIN");
190          currentBlock.addChild(block);
191          processParameters(block);
192          retrieveDataFromHeader(block);
193          consumeSpaces();
194          // end
195
match(HEADERDEF_END);
196          return true;
197       }
198             // reset in case of an exception
199
catch (CharStreamException exc) {
200          input.rewind(mark);
201       } catch (JagParserException exc) {
202          input.rewind(mark);
203       }
204       input.commit();
205       return false;
206    }
207
208
209    /**
210     * Method retrieveDataFromHeader
211     *
212     * Re-initialize the tag definitions. Gives the user an option to define
213     * the tag definition (start/end symbol) in header of the template. This
214     * to prevent incompatibilities between other tags. (jsp, html etc)
215     */

216    protected void retrieveDataFromHeader(JagBlock headerBlock) {
217       if (headerBlock.getType() != HEADERDEF_BEGIN)
218          return;
219
220       JagBlock childBlock = headerBlock.getFirstChild();
221       while (childBlock != null) {
222          if (childBlock.getType() == PARAMDEF) {
223             JagBlock childBlock2 = childBlock.getFirstChild();
224             if (childBlock2 != null && childBlock2.getType() == IDENT) {
225                if (childBlock2.getText().equals(getTokenString(TAGSTART))) {
226                   childBlock2 = childBlock2.getNextSibling();
227                   if (childBlock2 != null) {
228                      tagDefBegin = childBlock2.getText();
229                      tagDefBodyClose = tagDefBegin + getTokenString(TAGDEF_CLOSE);
230                   }
231                } else if (childBlock2.getText().equals(getTokenString(TAGEND))) {
232                   childBlock2 = childBlock2.getNextSibling();
233                   if (childBlock2 != null) {
234                      tagDefEnd = childBlock2.getText();
235                      tagDefClose = getTokenString(TAGDEF_CLOSE) + tagDefEnd;
236                   }
237                }
238             }
239          }
240          childBlock = childBlock.getNextSibling();
241       }
242    }
243
244
245    /**
246     * Method processTag
247     *
248     * Works with processTagBody()
249     * @return
250     *
251     */

252    protected boolean processTag() {
253       JagBlockImpl prevCurrentBlock = currentBlock;
254       int mark = input.mark();
255       try {
256          match(tagDefBegin);
257          JagBlockImpl blockTag = new JagBlockImpl();
258          blockTag.initialize(TAGSTART, "TAGSTART");
259
260          JagBlock endtagname = processIdent(TAGNAME);
261          blockTag.addChild(endtagname);
262          match(COLON);
263          JagBlock endtagaction = processIdent(TAGACTION);
264          blockTag.addChild(endtagaction);
265          processParameters(blockTag);
266
267          consumeSpaces();
268          if (ismatch(tagDefClose)) {
269             match(tagDefClose);
270             blockTag.setText(input.getCharsFromMark(mark));
271             currentBlock.addChild(blockTag);
272          } else {
273             match(tagDefEnd);
274             blockTag.setText(input.getCharsFromMark(mark));
275
276             // Insert TagBody
277
JagBlockImpl blockSlist = new JagBlockImpl();
278             blockSlist.initialize(SLIST, getTokenString(SLIST));
279             blockTag.addChild(blockSlist);
280             currentBlock = blockSlist;
281
282             // Process the tagbody
283
if (!processTagBody())
284                throw new JagParserException("Closing tag expected");
285
286             // Process the closing tag
287
int mark2 = input.mark();
288             match(tagDefBodyClose);
289             if (!endtagname.equals(processIdent(TAGNAME)))
290                throw new JagParserException("Invalid tag name in closing tag");
291             match(COLON);
292             if (!endtagaction.equals(processIdent(TAGACTION)))
293                throw new JagParserException("Infinite tag in closing tag");
294             match(tagDefEnd);
295
296             // insert end block
297
JagBlockImpl blockBodyEndTag = new JagBlockImpl();
298             blockBodyEndTag.initialize(TAGEND, input.getCharsFromMark(mark2));
299             blockTag.addChild(blockBodyEndTag);
300
301             // restore currentblock;
302
currentBlock = prevCurrentBlock;
303             currentBlock.addChild(blockTag);
304             // discard mark2
305
input.commit();
306          }
307          input.commit();
308          return true;
309       } catch (CharStreamException exc) {
310          input.rewind(mark);
311          currentBlock = prevCurrentBlock;
312       } catch (JagParserException exc) {
313          input.rewind(mark);
314          currentBlock = prevCurrentBlock;
315       }
316       return false;
317    }
318
319
320    /**
321     * Method processParameters
322     *
323     *
324     * @param blockRoot
325     *
326     * @throws CharStreamException
327     * @throws JagParserException
328     *
329     */

330    protected void processParameters(JagBlock blockRoot)
331          throws CharStreamException, JagParserException {
332       while (true) {
333          consumeSpaces();
334          StringBuffer JavaDoc text = new StringBuffer JavaDoc();
335          while (Character.isLetter(input.LA(1)) || (input.LA(1) == '_')) {
336             text.append(input.LA(1));
337             input.consume();
338          }
339          if (text.length() == 0) {
340             return;
341          }
342
343          consumeSpaces();
344
345          if (!ismatch(ASSIGN)) {
346             JagBlockImpl blockChild = new JagBlockImpl();
347             blockChild.initialize(IDENT, new String JavaDoc(text));
348             blockRoot.addChild(blockChild);
349             continue;
350          }
351
352          match(ASSIGN);
353
354          JagBlockImpl blockParamDef = new JagBlockImpl();
355          blockParamDef.initialize(PARAMDEF, getTokenString(PARAMDEF));
356          blockRoot.addChild(blockParamDef);
357
358          JagBlockImpl blockChild = new JagBlockImpl();
359          blockChild.initialize(IDENT, new String JavaDoc(text));
360          blockParamDef.addChild(blockChild);
361          consumeSpaces();
362
363          text = new StringBuffer JavaDoc();
364
365          if ((input.LA(1) == '"') && (input.LA(0) != '\\')) {
366             match("\"");
367             while (!((input.LA(1) == '"') && (input.LA(0) != '\\'))) {
368                text.append(input.LA(1));
369                input.consume();
370             }
371             match("\"");
372
373             JagBlockImpl blockString = new JagBlockImpl();
374
375             blockString.initialize(STRING, new String JavaDoc(text));
376             blockParamDef.addChild(blockString);
377          } else if ((input.LA(1) == '\'') && (input.LA(0) != '\\')) {
378             match("'");
379             while (!((input.LA(1) == '\'') && (input.LA(0) != '\\'))) {
380                text.append(input.LA(1));
381                input.consume();
382             }
383             match("'");
384
385             JagBlockImpl blockString = new JagBlockImpl();
386
387             blockString.initialize(STRING, new String JavaDoc(text));
388             blockParamDef.addChild(blockString);
389          } else {
390             boolean bInteger = true;
391             boolean bFloat = true;
392
393             while (Character.isDigit(input.LA(1))
394                   || Character.isLetter(input.LA(1))
395                   || (input.LA(1) == '_') || (input.LA(1) == '.')) {
396                if (!Character.isDigit(input.LA(1)) && (input.LA(1) != '.')) {
397                   bInteger = false;
398                   bFloat = false;
399                } else if (!Character.isDigit(input.LA(1))) {
400                   bInteger = false;
401                }
402
403                text.append(input.LA(1));
404                input.consume();
405             }
406
407             if (text.length() > 0) {
408                JagBlockImpl block = new JagBlockImpl();
409
410                block.initialize(bInteger ? INTEGER : bFloat ? FLOAT : STRING, new String JavaDoc(text));
411                blockParamDef.addChild(block);
412             } else {
413                throw new JagParserException("Invalid parameter definition");
414             }
415          }
416       }
417    }
418
419
420    protected JagBlock processIdent(int tagtype)
421          throws CharStreamException, JagParserException {
422       StringBuffer JavaDoc text = new StringBuffer JavaDoc();
423       while (Character.isLetter(input.LA(1)) || (input.LA(1) == '_')) {
424          text.append(input.LA(1));
425          input.consume();
426       }
427       if (text.length() < 1)
428          throw new JagParserException("Identifier expected");
429
430       JagBlockImpl blockChild = new JagBlockImpl();
431       blockChild.initialize(tagtype, new String JavaDoc(text));
432       return blockChild;
433    }
434
435
436    /**
437     * Method consumeComment
438     *
439     * @throws CharStreamException
440     * @throws JagParserException
441     */

442    protected void consumeComment()
443          throws CharStreamException, JagParserException {
444       match(tagDefBegin + getTokenString(COMMENT_BEGIN));
445       while (EOF_CHAR != input.LA(1) && !ismatch(getTokenString(COMMENT_END) + tagDefBegin)) {
446          input.consume();
447       }
448       match(getTokenString(COMMENT_END) + tagDefBegin);
449    }
450
451
452    /**
453     * Method isTagDefinition
454     *
455     *
456     * @return
457     *
458     */

459    protected boolean isTagDefinition() {
460       return ismatch(tagDefBegin) && !ismatch(tagDefEnd);
461    }
462
463
464    /**
465     * Method isHeaderDefinition
466     *
467     *
468     * @return
469     *
470     */

471    protected boolean isHeaderDefinition() {
472       return ismatch(HEADERDEF_BEGIN);
473    }
474
475
476    /**
477     * Method isCommentDefinition
478     *
479     *
480     * @return
481     *
482     */

483    protected boolean isCommentDefinition() {
484       return ismatch(tagDefBegin + getTokenString(COMMENT_BEGIN));
485    }
486
487
488    /**
489     * Method isTagDefBodyClose
490     *
491     *
492     * @return
493     *
494     */

495    protected boolean isTagDefBodyClose() {
496
497       if (!ismatch(tagDefBodyClose))
498          return false;
499
500       int mark = input.mark();
501       boolean returnValue = true;
502       try {
503          match(tagDefBodyClose);
504          processIdent(TAGNAME);
505          match(COLON);
506          processIdent(TAGACTION);
507          match(tagDefEnd);
508       } catch (Exception JavaDoc e) {
509          returnValue = false;
510       }
511       input.rewind(mark);
512       return returnValue;
513    }
514
515
516    /**
517     * Method getJagBlockCollection
518     *
519     *
520     * @return
521     *
522     */

523    public final JagBlockCollection getJagBlockCollection() {
524       return lnkJagBlockCollection;
525    }
526
527
528    /**
529     * Method consumeSpaces
530     *
531     *
532     * @return
533     *
534     * @throws CharStreamException
535     * @throws JagParserException
536     *
537     */

538    protected int consumeSpaces() throws CharStreamException, JagParserException {
539       int nCounter = 0;
540
541       while (true) {
542          if (Character.isWhitespace(input.LA(1)) || (input.LA(1) == '\n')) {
543             input.consume();
544             nCounter++;
545          } else if (input.LAChars(2) == "\r\n") {
546             match("\r\n");
547             nCounter += 2;
548          } else {
549             break;
550          }
551       }
552
553       return nCounter;
554    }
555
556
557    /**
558     * Method match
559     *
560     *
561     * @param token
562     *
563     * @throws CharStreamException
564     * @throws JagParserException
565     *
566     */

567    protected void match(int token) throws CharStreamException, JagParserException {
568       match(getTokenString(token));
569    }
570
571
572    /**
573     * Method match
574     *
575     *
576     * @param s
577     *
578     * @throws CharStreamException
579     * @throws JagParserException
580     *
581     */

582    protected void match(String JavaDoc s) throws CharStreamException, JagParserException {
583       StringBuffer JavaDoc text = new StringBuffer JavaDoc();
584
585       for (int i = 0; i < s.length(); i++) {
586          text.append(input.LA(1));
587
588          if (s.charAt(i) != input.LA(1)) {
589             throw new JagParserException("\" " + s
590                   + " \" excpected, found \" "
591                   + text.toString() + " \"");
592          }
593          input.consume();
594       }
595    }
596
597
598    /**
599     * Method ismatch
600     *
601     *
602     * @param token
603     *
604     * @return
605     *
606     */

607    protected boolean ismatch(int token) {
608       return ismatch(getTokenString(token));
609    }
610
611
612    /**
613     * Method ismatch
614     *
615     *
616     * @param s
617     *
618     * @return
619     *
620     */

621    protected boolean ismatch(String JavaDoc s) {
622       try {
623          String JavaDoc sChars = input.LAChars(s.length());
624          return sChars.compareTo(s) == 0;
625       } catch (CharStreamException exc) {
626       }
627
628       return false;
629    }
630
631
632    /**
633     * Method getTokenString
634     *
635     *
636     * @param n
637     *
638     * @return
639     *
640     */

641    protected String JavaDoc getTokenString(int n) {
642       return tokennames[n];
643    }
644 }
645
646 ;
Popular Tags