KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > text > SimpleTemplateEngine


1 /*
2  * $Id: SimpleTemplateEngine.java,v 1.13 2004/12/08 22:45:33 spullara Exp $version Mar 8, 2004 2:11:00 AM $user Exp $
3  *
4  * Copyright 2003 (C) Sam Pullara. All Rights Reserved.
5  *
6  * Redistribution and use of this software and associated documentation
7  * ("Software"), with or without modification, are permitted provided that the
8  * following conditions are met: 1. Redistributions of source code must retain
9  * copyright statements and notices. Redistributions must also contain a copy
10  * of this document. 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer in
12  * the documentation and/or other materials provided with the distribution. 3.
13  * The name "groovy" must not be used to endorse or promote products derived
14  * from this Software without prior written permission of The Codehaus. For
15  * written permission, please contact info@codehaus.org. 4. Products derived
16  * from this Software may not be called "groovy" nor may "groovy" appear in
17  * their names without prior written permission of The Codehaus. "groovy" is a
18  * registered trademark of The Codehaus. 5. Due credit should be given to The
19  * Codehaus - http://groovy.codehaus.org/
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY
22  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  *
33  */

34  package groovy.text;
35
36 import groovy.lang.Binding;
37 import groovy.lang.GroovyShell;
38 import groovy.lang.Script;
39 import groovy.lang.Writable;
40
41 import java.io.BufferedReader JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.PrintWriter JavaDoc;
44 import java.io.Reader JavaDoc;
45 import java.io.StringWriter JavaDoc;
46 import java.io.Writer JavaDoc;
47 import java.util.Map JavaDoc;
48
49 import org.codehaus.groovy.control.CompilationFailedException;
50 import org.codehaus.groovy.runtime.InvokerHelper;
51
52
53 /**
54  * This simple template engine uses JSP <% %> script and <%= %> expression syntax. It also lets you use normal groovy expressions in
55  * the template text much like the new JSP EL functionality. The variable 'out' is bound to the writer that the template is being written to.
56  *
57  * @author sam
58  */

59 public class SimpleTemplateEngine extends TemplateEngine {
60
61     /* (non-Javadoc)
62      * @see groovy.util.TemplateEngine#createTemplate(java.io.Reader)
63      */

64     public Template createTemplate(Reader JavaDoc reader) throws CompilationFailedException, ClassNotFoundException JavaDoc, IOException JavaDoc {
65         SimpleTemplate template = new SimpleTemplate();
66         GroovyShell shell = new GroovyShell();
67         String JavaDoc script = template.parse(reader);
68         template.script = shell.parse(script);
69         return template;
70     }
71         
72     private static class SimpleTemplate implements Template {
73         
74         private Script script;
75
76         public Writable make() {
77             return make(null);
78         }
79
80         public Writable make(final Map JavaDoc map) {
81             return new Writable() {
82                 /**
83                  * Write the template document with the set binding applied to the writer.
84                  *
85                  * @see groovy.lang.Writable#writeTo(java.io.Writer)
86                  */

87                 public Writer JavaDoc writeTo(Writer JavaDoc writer) throws IOException JavaDoc {
88                     Binding binding;
89                     if (map == null) binding = new Binding(); else binding = new Binding(map);
90                     Script scriptObject = InvokerHelper.createScript(script.getClass(), binding);
91                     PrintWriter JavaDoc pw = new PrintWriter JavaDoc(writer);
92                     scriptObject.setProperty("out", pw);
93                     scriptObject.run();
94                     pw.flush();
95                     return writer;
96                 }
97
98                 /**
99                  * Convert the template and binding into a result String.
100                  *
101                  * @see java.lang.Object#toString()
102                  */

103                 public String JavaDoc toString() {
104                     try {
105                         StringWriter JavaDoc sw = new StringWriter JavaDoc();
106                         writeTo(sw);
107                         return sw.toString();
108                     } catch (Exception JavaDoc e) {
109                         return e.toString();
110                     }
111                 }
112             };
113         }
114
115         /**
116          * Parse the text document looking for <% or <%= and then call out to the appropriate handler, otherwise copy the text directly
117          * into the script while escaping quotes.
118          *
119          * @param reader
120          * @return
121          * @throws IOException
122          */

123         private String JavaDoc parse(Reader JavaDoc reader) throws IOException JavaDoc {
124             if (!reader.markSupported()) {
125                 reader = new BufferedReader JavaDoc(reader);
126             }
127             StringWriter JavaDoc sw = new StringWriter JavaDoc();
128             startScript(sw);
129             boolean start = false;
130             int c;
131             while((c = reader.read()) != -1) {
132                 if (c == '<') {
133                     reader.mark(1);
134                     c = reader.read();
135                     if (c != '%') {
136                         sw.write('<');
137                         reader.reset();
138                         continue;
139                     } else {
140                         reader.mark(1);
141                         c = reader.read();
142                         if (c == '=') {
143                             groovyExpression(reader, sw);
144                         } else {
145                             reader.reset();
146                             groovySection(reader, sw);
147                         }
148                         continue;
149                     }
150                 }
151                 if (c == '\"') {
152                     sw.write('\\');
153                 }
154                 sw.write(c);
155             }
156             endScript(sw);
157             String JavaDoc result = sw.toString();
158             //System.out.println( "source text:\n" + result );
159
return result;
160         }
161
162         private void startScript(StringWriter JavaDoc sw) {
163             sw.write("/* Generated by SimpleTemplateEngine */ ");
164             sw.write("out.print(\"");
165         }
166
167         private void endScript(StringWriter JavaDoc sw) {
168             sw.write("\");\n");
169         }
170
171         /**
172          * Closes the currently open write and writes out the following text as a GString expression until it reaches an end %>.
173          *
174          * @param reader
175          * @param sw
176          * @throws IOException
177          */

178         private void groovyExpression(Reader JavaDoc reader, StringWriter JavaDoc sw) throws IOException JavaDoc {
179             sw.write("\");out.print(\"${");
180             int c;
181             while((c = reader.read()) != -1) {
182                 if (c == '%') {
183                     c = reader.read();
184                     if (c != '>') {
185                         sw.write('%');
186                     } else {
187                         break;
188                     }
189                 }
190                 sw.write(c);
191             }
192             sw.write("}\");out.print(\"");
193         }
194
195         /**
196          * Closes the currently open write and writes the following text as normal Groovy script code until it reaches an end %>.
197          *
198          * @param reader
199          * @param sw
200          * @throws IOException
201          */

202         private void groovySection(Reader JavaDoc reader, StringWriter JavaDoc sw) throws IOException JavaDoc {
203             sw.write("\");");
204             int c;
205             while((c = reader.read()) != -1) {
206                 if (c == '%') {
207                     c = reader.read();
208                     if (c != '>') {
209                         sw.write('%');
210                     } else {
211                         break;
212                     }
213                 }
214                 sw.write(c);
215             }
216             sw.write(";out.print(\"");
217         }
218
219     }
220 }
221
Popular Tags