View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jelly.tags.core;
17  
18  import java.io.FileNotFoundException;
19  import java.io.FileOutputStream;
20  import java.io.IOException;
21  import java.io.OutputStreamWriter;
22  import java.io.StringWriter;
23  import java.io.UnsupportedEncodingException;
24  import java.io.Writer;
25  
26  import org.apache.commons.jelly.JellyTagException;
27  import org.apache.commons.jelly.TagSupport;
28  import org.apache.commons.jelly.XMLOutput;
29  import org.apache.commons.jelly.util.SafeContentHandler;
30  import org.dom4j.io.HTMLWriter;
31  import org.dom4j.io.OutputFormat;
32  import org.dom4j.io.XMLWriter;
33  import org.xml.sax.SAXException;
34  
35  /***
36   * A tag that pipes its body to a file denoted by the name attribute or to an in memory String
37   * which is then output to a variable denoted by the var variable.
38   *
39   * @author <a href="mailto:vinayc@apache.org">Vinay Chandran</a>
40   */
41  public class FileTag extends TagSupport {
42      private boolean doAppend = false;
43      private String var;
44      private String name;
45      private boolean omitXmlDeclaration = false;
46      private String outputMode = "xml";
47      private boolean prettyPrint;
48      private String encoding;
49  
50      public FileTag(){
51      }
52  
53      // Tag interface
54      //-------------------------------------------------------------------------
55      public void doTag(final XMLOutput output) throws JellyTagException {
56          try {
57              if ( name != null ) {
58                  String encoding = (this.encoding != null) ? this.encoding : "UTF-8";
59                  Writer writer = new OutputStreamWriter( new FileOutputStream( name, doAppend ), encoding );
60                  writeBody(writer);
61              }
62              else if (var != null) {
63                  StringWriter writer = new StringWriter();
64                  writeBody(writer);
65                  String result = writer.toString();
66                  Object varValue = context.getVariable(var);
67                  // if we're appending, and var is an instance of string, append it.
68                  if (doAppend && varValue instanceof String) {
69                      context.setVariable(var, varValue + result);
70                  } else {
71                      context.setVariable(var, result);
72                  }
73              }
74              else {
75                  throw new JellyTagException( "This tag must have either the 'name' or the 'var' variables defined" );
76              }
77          } catch (FileNotFoundException e) {
78              throw new JellyTagException(e);
79          } catch (UnsupportedEncodingException e) {
80              throw new JellyTagException(e);
81          } catch (SAXException e) {
82              throw new JellyTagException("could not write file",e);
83          }
84      }
85  
86      // Properties
87      //-------------------------------------------------------------------------
88  
89      /***
90       * Sets the file name for the output
91       */
92      public void setName(String name) {
93          this.name = name;
94      }
95  
96      /***
97       * Sets whether the XML declaration should be output or not
98       */
99      public void setOmitXmlDeclaration(boolean omitXmlDeclaration) {
100         this.omitXmlDeclaration = omitXmlDeclaration;
101     }
102 
103 
104     /***
105      * Sets the output mode, whether XML or HTML
106      */
107     public void setOutputMode(String outputMode) {
108         this.outputMode = outputMode;
109     }
110 
111     /***
112      * Sets whether pretty printing mode is turned on. The default is off so that whitespace is preserved
113      */
114     public void setPrettyPrint(boolean prettyPrint) {
115         this.prettyPrint = prettyPrint;
116     }
117 
118     /***
119      * Sets the XML encoding mode, which defaults to UTF-8
120      */
121     public void setEncoding(String encoding) {
122         this.encoding = encoding;
123     }
124     
125     /***
126      * Sets wether to append at the end of the file
127      * (not really something you normally do with an XML file).
128      */
129     public void setAppend(boolean doAppend) {
130         this.doAppend = doAppend;
131     }
132     
133 
134     /***
135      * Returns the var.
136      * @return String
137      */
138     public String getVar() {
139         return var;
140     }
141 
142     /***
143      * Sets the var.
144      * @param var The var to set
145      */
146     public void setVar(String var) {
147         this.var = var;
148     }
149 
150     /***
151      * Writes the body fo this tag to the given Writer
152      */
153     protected void writeBody(Writer writer) throws SAXException, JellyTagException {
154 
155         XMLOutput newOutput = createXMLOutput(writer);
156         try {
157             // we need to avoid multiple start/end document events
158             newOutput.setContentHandler(
159                 new SafeContentHandler(newOutput.getContentHandler())
160             );
161             newOutput.startDocument();
162             invokeBody(newOutput);
163             newOutput.endDocument();
164         }
165         finally {
166             try { newOutput.close(); } catch (IOException e) {}
167         }
168     }
169 
170     /***
171      * A Factory method to create a new XMLOutput from the given Writer.
172      */
173     protected XMLOutput createXMLOutput(Writer writer) {
174 
175         OutputFormat format = null;
176         if (prettyPrint) {
177             format = OutputFormat.createPrettyPrint();
178         }
179         else {
180             format = new OutputFormat();
181         }
182         if ( encoding != null ) {
183             format.setEncoding( encoding );
184         }
185         if ( omitXmlDeclaration ) {
186             format.setSuppressDeclaration(true);
187         }
188 
189         boolean isHtml = outputMode != null && outputMode.equalsIgnoreCase( "html" );
190         final XMLWriter xmlWriter = (isHtml)
191             ? new HTMLWriter(writer, format)
192             : new XMLWriter(writer, format);
193 
194         xmlWriter.setEscapeText(isEscapeText());
195 
196         XMLOutput answer = new XMLOutput() {
197             public void close() throws IOException {
198                 xmlWriter.close();
199             }
200         };
201         answer.setContentHandler(xmlWriter);
202         answer.setLexicalHandler(xmlWriter);
203         return answer;
204     }
205 }