View Javadoc

1   package org.apache.commons.jelly.tags.velocity;
2   
3   /*
4    * Copyright 2001,2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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      // -- Tag interface -----------------------------------------------------
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      // -- Properties --------------------------------------------------------
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     // -- Implementation ----------------------------------------------------
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