KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > codegen > jet > JETParser


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2005 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: JETParser.java,v 1.6 2005/06/12 13:19:04 emerks Exp $
16  *
17  * The Apache Software License, Version 1.1
18  *
19  * Copyright (c) 1999 The Apache Software Foundation. All rights
20  * reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  *
26  * 1. Redistributions of source code must retain the above copyright
27  * notice, this list of conditions and the following disclaimer.
28  *
29  * 2. Redistributions in binary form must reproduce the above copyright
30  * notice, this list of conditions and the following disclaimer in
31  * the documentation and/or other materials provided with the
32  * distribution.
33  *
34  * 3. The end-user documentation included with the redistribution, if
35  * any, must include the following acknowlegement:
36  * "This product includes software developed by the
37  * Apache Software Foundation (http://www.apache.org/)."
38  * Alternately, this acknowlegement may appear in the software itself,
39  * if and wherever such third-party acknowlegements normally appear.
40  *
41  * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
42  * Foundation" must not be used to endorse or promote products derived
43  * from this software without prior written permission. For written
44  * permission, please contact apache@apache.org.
45  *
46  * 5. Products derived from this software may not be called "Apache"
47  * nor may "Apache" appear in their names without prior written
48  * permission of the Apache Group.
49  *
50  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
51  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
52  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
54  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
57  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
59  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
60  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61  * SUCH DAMAGE.
62  * ====================================================================
63  *
64  * This software consists of voluntary contributions made by many
65  * individuals on behalf of the Apache Software Foundation. For more
66  * information on the Apache Software Foundation, please see
67  * <http://www.apache.org/>.
68  */

69 package org.eclipse.emf.codegen.jet;
70
71
72 import java.io.CharArrayWriter JavaDoc;
73 import java.io.IOException JavaDoc;
74 import java.util.ArrayList JavaDoc;
75 import java.util.Collection JavaDoc;
76 import java.util.Iterator JavaDoc;
77 import java.util.List JavaDoc;
78 import java.util.Map JavaDoc;
79
80 import org.eclipse.emf.codegen.CodeGenPlugin;
81
82
83 /**
84  * This class and all those in this package is work derived from contributions of multiple authors as listed below.
85  * Credit for all that is good is shared, responsibility for any problems lies solely with the latest authors.
86  *
87  * @author Anil K. Vijendran
88  * @author Anselm Baird-Smith
89  * @author David Charboneau
90  * @author Harish Prabandham
91  * @author Kevin Bauer
92  * @author Mandar Raje
93  * @author Paul R. Hoffman
94  * @author Rajiv Mordani
95  */

96 public class JETParser
97 {
98   public interface Action
99   {
100     void execute() throws JETException;
101   }
102
103   public static class DelegatingListener implements JETParseEventListener
104   {
105     protected JETParseEventListener delegate;
106     protected JETParser.Action action;
107
108     public DelegatingListener(JETParseEventListener delegate, JETParser.Action action)
109     {
110       this.delegate = delegate;
111       this.action = action;
112     }
113
114     public void doAction() throws JETException
115     {
116       action.execute();
117     }
118
119     public void beginPageProcessing() throws JETException
120     {
121       delegate.beginPageProcessing();
122     }
123
124     public void endPageProcessing() throws JETException
125     {
126       delegate.endPageProcessing();
127     }
128
129     public void handleDirective(String JavaDoc directive, JETMark start, JETMark stop, Map JavaDoc attrs)
130         throws JETException
131     {
132       doAction();
133       delegate.handleDirective(directive, start, stop, attrs);
134     }
135
136     public void handleScriptlet(JETMark start, JETMark stop, Map JavaDoc attrs) throws JETException
137     {
138       doAction();
139       delegate.handleScriptlet(start, stop, attrs);
140     }
141
142     public void handleExpression(JETMark start, JETMark stop, Map JavaDoc attrs) throws JETException
143     {
144       doAction();
145       delegate.handleExpression(start, stop, attrs);
146     }
147
148     public void handleCharData(char[] chars) throws JETException
149     {
150       delegate.handleCharData(chars);
151     }
152   }
153
154   /**
155    * The input source we read from...
156    */

157   protected JETReader reader;
158
159   /**
160    * The backend that is notified of constructs recognized in the input...
161    */

162   protected JETParseEventListener listener;
163
164   /*
165    * Char buffer for HTML data
166    */

167   protected CharArrayWriter JavaDoc writer;
168
169   protected List JavaDoc coreElements = new ArrayList JavaDoc();
170
171   protected String JavaDoc openDirective = "<%@";
172   protected String JavaDoc closeDirective = "%>";
173
174   protected String JavaDoc openScriptlet = "<%";
175   protected String JavaDoc closeScriptlet = "%>";
176
177   protected String JavaDoc openExpr = "<%=";
178   protected String JavaDoc closeExpr = "%>";
179
180   protected String JavaDoc quotedStartTag = "<\\%";
181   protected String JavaDoc quotedEndTag = "%\\>";
182   protected String JavaDoc startTag = "<%";
183   protected String JavaDoc endTag = "%>";
184
185   public JETParser(JETReader reader, final JETParseEventListener parseEventListener, JETCoreElement[] coreElements)
186   {
187     this.reader = reader;
188     this.listener =
189       new DelegatingListener
190         (parseEventListener,
191          new Action()
192          {
193            public void execute() throws JETException
194            {
195              JETParser.this.flushCharData();
196            }
197          });
198
199     this.writer = new CharArrayWriter JavaDoc();
200
201     for (int i = 0; i < coreElements.length; i++)
202     {
203       this.coreElements.add(coreElements[i]);
204     }
205   }
206
207   public JETReader getReader()
208   {
209     return reader;
210   }
211
212   public void setStartTag(String JavaDoc tag)
213   {
214     openScriptlet = tag;
215     openExpr = tag + "=";
216     openDirective = tag + "@";
217     quotedStartTag = tag.charAt(0) + "\\" + tag.charAt(1);
218     startTag = tag;
219     reader.setStartTag(tag);
220   }
221
222   public void setEndTag(String JavaDoc tag)
223   {
224     closeScriptlet = tag;
225     closeExpr = tag;
226     closeDirective = tag;
227     quotedEndTag = tag.charAt(0) + "\\" + tag.charAt(1);
228     endTag = tag;
229     reader.setEndTag(tag);
230   }
231
232   public String JavaDoc getOpenScriptlet()
233   {
234     return openScriptlet;
235   }
236
237   public String JavaDoc getCloseScriptlet()
238   {
239     return closeScriptlet;
240   }
241
242   public String JavaDoc getOpenExpr()
243   {
244     return openExpr;
245   }
246
247   public String JavaDoc getCloseExpr()
248   {
249     return closeExpr;
250   }
251
252   public String JavaDoc getOpenDirective()
253   {
254     return openDirective;
255   }
256
257   public String JavaDoc getCloseDirective()
258   {
259     return closeDirective;
260   }
261
262   public String JavaDoc getQuotedStartTag()
263   {
264     return quotedStartTag;
265   }
266
267   public String JavaDoc getQuotedEndTag()
268   {
269     return quotedEndTag;
270   }
271
272   public String JavaDoc getStartTag()
273   {
274     return startTag;
275   }
276
277   public String JavaDoc getEndTag()
278   {
279     return endTag;
280   }
281
282   public static class Scriptlet implements JETCoreElement
283   {
284     public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException
285     {
286       String JavaDoc close, open, end_open = null;
287       Map JavaDoc attrs = null;
288
289       if (reader.matches(parser.getOpenScriptlet()))
290       {
291         open = parser.getOpenScriptlet();
292         close = parser.getCloseScriptlet();
293       }
294       else
295       {
296         return false;
297       }
298
299       reader.advance(open.length());
300
301       if (end_open != null)
302       {
303         attrs = reader.parseTagAttributes();
304
305         reader.skipSpaces();
306         if (!reader.matches(end_open))
307         {
308           throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.unterminated", new Object JavaDoc [] { open, reader.mark().toString() }));
309         }
310         reader.advance(end_open.length());
311         reader.skipSpaces();
312       }
313
314       JETMark start = reader.mark();
315       JETMark stop = reader.skipUntil(close);
316       if (stop == null)
317       {
318         throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.unterminated", new Object JavaDoc[] { open, reader.mark().toString() }));
319       }
320       listener.handleScriptlet(start, stop, attrs);
321       return true;
322     }
323   }
324
325   public static class Expression implements JETCoreElement
326   {
327     public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException
328     {
329       String JavaDoc close, open;
330       Map JavaDoc attrs = null;
331
332       if (reader.matches(parser.getOpenExpr()))
333       {
334         open = parser.getOpenExpr();
335         close = parser.getCloseExpr();
336       }
337       else
338       {
339         return false;
340       }
341
342       reader.advance(open.length());
343
344       JETMark start = reader.mark();
345       JETMark stop = reader.skipUntil(close);
346       if (stop == null)
347       {
348         throw new JETException(CodeGenPlugin.getPlugin().getString("jet.error.unterminated", new Object JavaDoc[] { open, reader.mark().toString() }));
349       }
350       listener.handleExpression(start, stop, attrs);
351       return true;
352     }
353   }
354
355   /**
356    * Quoting in template text.
357    * Entities &apos; and &quote;
358    */

359   public static class QuoteEscape implements JETCoreElement
360   {
361     /**
362      * constants for escapes
363      */

364     protected static final String JavaDoc APOS = "&apos;";
365     protected static final String JavaDoc QUOTE = "&quote;";
366
367     public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException
368     {
369       try
370       {
371         if (reader.matches(parser.getQuotedEndTag()))
372         {
373           reader.advance(parser.getQuotedEndTag().length());
374           parser.writer.write(parser.getEndTag());
375           parser.flushCharData();
376           return true;
377         }
378         else if (reader.matches(APOS))
379         {
380           reader.advance(APOS.length());
381           parser.writer.write("\'");
382           parser.flushCharData();
383           return true;
384         }
385         else if (reader.matches(QUOTE))
386         {
387           reader.advance(QUOTE.length());
388           parser.writer.write("\"");
389           parser.flushCharData();
390           return true;
391         }
392       }
393       catch (IOException JavaDoc exception)
394       {
395         throw new JETException(exception);
396       }
397       return false;
398     }
399   }
400
401   public static class Directive implements JETCoreElement
402   {
403     protected Collection JavaDoc directives = new ArrayList JavaDoc();
404
405     public boolean accept(JETParseEventListener listener, JETReader reader, JETParser parser) throws JETException
406     {
407       if (reader.matches(parser.getOpenDirective()))
408       {
409         JETMark start = reader.mark();
410         reader.advance(parser.getOpenDirective().length());
411         reader.skipSpaces();
412
413         // Check which directive it is.
414
//
415
String JavaDoc match = null;
416
417         for (Iterator JavaDoc i = directives.iterator(); i.hasNext(); )
418         {
419           String JavaDoc directive = (String JavaDoc)i.next();
420           if (reader.matches(directive))
421           {
422             match = directive;
423             break;
424           }
425         }
426
427         if (match == null)
428         {
429           throw
430             new JETException
431               (CodeGenPlugin.getPlugin().getString
432                 ("jet.error.bad.directive",
433                  new Object JavaDoc [] { start.format("jet.mark.file.line.column") }));
434           //reader.reset(start);
435
//return false;
436
}
437
438         reader.advance(match.length());
439
440         // Parse the attr-val pairs.
441
//
442
Map JavaDoc attrs = reader.parseTagAttributes();
443
444         // Match close.
445
reader.skipSpaces();
446         if (!reader.matches(parser.getCloseDirective()))
447         {
448           throw
449             new JETException
450               (CodeGenPlugin.getPlugin().getString
451                 ("jet.error.unterminated", new Object JavaDoc[] { parser.getOpenDirective(), reader.mark().toString() }));
452         }
453         else
454         {
455           reader.advance(parser.getCloseDirective().length());
456         }
457
458         JETMark stop = reader.mark();
459         listener.handleDirective(match, start, stop, attrs);
460         return true;
461       }
462       else
463       {
464         return false;
465       }
466     }
467
468     public Collection JavaDoc getDirectives()
469     {
470       return directives;
471     }
472   }
473
474   protected void flushCharData() throws JETException
475   {
476     char[] array = writer.toCharArray();
477     if (array.length != 0) // Avoid unnecessary out.write("") statements...
478
{
479       listener.handleCharData(writer.toCharArray());
480     }
481     writer = new CharArrayWriter JavaDoc();
482   }
483
484   public void parse() throws JETException
485   {
486     parse(null);
487   }
488
489   public void parse(String JavaDoc until) throws JETException
490   {
491     parse(until, null);
492   }
493
494   public void parse(String JavaDoc until, Class JavaDoc[] accept) throws JETException
495   {
496     while (reader.hasMoreInput())
497     {
498       if (until != null && reader.matches(until))
499       {
500         return;
501       }
502
503       Iterator JavaDoc e = coreElements.iterator();
504
505       if (accept != null)
506       {
507         List JavaDoc v = new ArrayList JavaDoc();
508         while (e.hasNext())
509         {
510           JETCoreElement c = (JETCoreElement) e.next();
511           for(int i = 0; i < accept.length; i++)
512           {
513             if (c.getClass().equals(accept[i]))
514             {
515               v.add(c);
516             }
517           }
518         }
519         e = v.iterator();
520       }
521
522       boolean accepted = false;
523       while (e.hasNext())
524       {
525         JETCoreElement c = (JETCoreElement) e.next();
526         reader.mark();
527         if (c.accept(listener, reader, this))
528         {
529           accepted = true;
530           break;
531         }
532       }
533       if (!accepted)
534       {
535         String JavaDoc s = reader.nextContent();
536         writer.write(s, 0, s.length());
537       }
538     }
539     flushCharData();
540   }
541 }
542
Popular Tags