1 package org.apache.commons.jelly.tags.velocity;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import org.apache.commons.jelly.JellyTagException;
20 import org.apache.commons.jelly.XMLOutput;
21
22 import org.apache.velocity.exception.MethodInvocationException;
23 import org.apache.velocity.exception.ParseErrorException;
24 import org.apache.velocity.exception.ResourceNotFoundException;
25
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.OutputStreamWriter;
29 import java.io.StringWriter;
30 import java.io.Writer;
31
32 /***
33 * A tag that uses Velocity to render a specified template with the
34 * JellyContext storing the results in either a variable in the
35 * JellyContext or in a specified file.
36 *
37 * @author <a href="mailto:pete-apache-dev@kazmier.com">Pete Kazmier</a>
38 * @version $Id: MergeTag.java 155420 2005-02-26 13:06:03Z dirkv $
39 */
40 public class MergeTag extends VelocityTagSupport
41 {
42 private static final String ENCODING = "ISO-8859-1";
43
44 private String var;
45 private String name;
46 private String basedir;
47 private String template;
48 private String inputEncoding;
49 private String outputEncoding;
50 private boolean readOnly = true;
51
52
53
54 public void doTag( final XMLOutput output ) throws JellyTagException
55 {
56 if ( basedir == null || template == null )
57 {
58 throw new JellyTagException(
59 "This tag must define 'basedir' and 'template'" );
60 }
61
62 if ( name != null )
63 {
64 try {
65 Writer writer = new OutputStreamWriter(
66 new FileOutputStream( name ),
67 outputEncoding == null ? ENCODING : outputEncoding );
68 mergeTemplate( writer );
69 writer.close();
70 }
71 catch (IOException e) {
72 throw new JellyTagException(e);
73 }
74 }
75 else if ( var != null )
76 {
77 StringWriter writer = new StringWriter();
78 mergeTemplate( writer );
79 context.setVariable( var, writer.toString() );
80 }
81 else
82 {
83 throw new JellyTagException(
84 "This tag must define either 'name' or 'var'" );
85 }
86 }
87
88
89
90 /***
91 * Sets the var used to store the results of the merge.
92 *
93 * @param var The var to set in the JellyContext with the results of
94 * the merge.
95 */
96 public void setVar( String var )
97 {
98 this.var = var;
99 }
100
101 /***
102 * Sets the file name for the merged output.
103 *
104 * @param name The name of the output file that is used to store the
105 * results of the merge.
106 */
107 public void setName( String name )
108 {
109 this.name = name;
110 }
111
112 /***
113 * Sets the base directory used for loading of templates by the
114 * Velocity file resource loader.
115 *
116 * @param basedir The directory where templates can be located by
117 * the Velocity file resource loader.
118 */
119 public void setBasedir( String basedir )
120 {
121 this.basedir = basedir;
122 }
123
124 /***
125 * Sets the filename of the template used to merge with the
126 * JellyContext.
127 *
128 * @param template The filename of the template to be merged.
129 */
130 public void setTemplate( String template )
131 {
132 this.template = template;
133 }
134
135 /***
136 * Sets the read-only flag for this adapter which prevents
137 * modifications in the Velocity context from propogating to the
138 * JellyContext.
139 *
140 * @param readOnly <tt>true</tt> prevents modifications from
141 * propogating (the default), or <tt>false</tt> which permits
142 * modifications.
143 */
144 public void setReadOnly( boolean readOnly )
145 {
146 this.readOnly = readOnly;
147 }
148
149 /***
150 * Sets the output encoding mode which defaults to ISO-8859-1 used
151 * when storing the results of a merge in a file.
152 *
153 * @param encoding The file encoding to use when writing the
154 * output.
155 */
156 public void setOutputEncoding( String encoding )
157 {
158 this.outputEncoding = encoding;
159 }
160
161 /***
162 * Sets the input encoding used in the specified template which
163 * defaults to ISO-8859-1.
164 *
165 * @param encoding The encoding used in the template.
166 */
167 public void setInputEncoding( String encoding )
168 {
169 this.inputEncoding = encoding;
170 }
171
172
173
174 /***
175 * Merges the Velocity template with the Jelly context.
176 *
177 * @param writer The output writer used to write the merged results.
178 * @throws Exception If an exception occurs during the merge.
179 */
180 private void mergeTemplate( Writer writer ) throws JellyTagException
181 {
182 JellyContextAdapter adapter = new JellyContextAdapter( getContext() );
183 adapter.setReadOnly( readOnly );
184
185 try {
186 getVelocityEngine( basedir ).mergeTemplate(
187 template,
188 inputEncoding == null ? ENCODING : inputEncoding,
189 adapter,
190 writer );
191 }
192 catch (ResourceNotFoundException e) {
193 throw new JellyTagException(e);
194 }
195 catch (ParseErrorException e) {
196 throw new JellyTagException(e);
197 }
198 catch (MethodInvocationException e) {
199 throw new JellyTagException(e);
200 }
201 catch (Exception e) {
202 throw new JellyTagException(e);
203 }
204 }
205 }
206