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 String var;
43      private String name;
44      private boolean omitXmlDeclaration = false;
45      private String outputMode = "xml";
46      private boolean prettyPrint;
47      private String encoding;
48  
49      public FileTag(){
50      }
51  
52      // Tag interface
53      //-------------------------------------------------------------------------
54      public void doTag(final XMLOutput output) throws JellyTagException {
55          try {
56              if ( name != null ) {
57                  String encoding = (this.encoding != null) ? this.encoding : "UTF-8";
58                  Writer writer = new OutputStreamWriter( new FileOutputStream( name ), encoding );
59                  writeBody(writer);
60              }
61              else if (var != null) {
62                  StringWriter writer = new StringWriter();
63                  writeBody(writer);
64                  context.setVariable(var, writer.toString());
65              }
66              else {
67                  throw new JellyTagException( "This tag must have either the 'name' or the 'var' variables defined" );
68              }
69          } catch (FileNotFoundException e) {
70              throw new JellyTagException(e);
71          } catch (UnsupportedEncodingException e) {
72              throw new JellyTagException(e);
73          } catch (SAXException e) {
74              throw new JellyTagException("could not write file",e);
75          }
76      }
77  
78      // Properties
79      //-------------------------------------------------------------------------
80  
81      /***
82       * Sets the file name for the output
83       */
84      public void setName(String name) {
85          this.name = name;
86      }
87  
88      /***
89       * Sets whether the XML declaration should be output or not
90       */
91      public void setOmitXmlDeclaration(boolean omitXmlDeclaration) {
92          this.omitXmlDeclaration = omitXmlDeclaration;
93      }
94  
95  
96      /***
97       * Sets the output mode, whether XML or HTML
98       */
99      public void setOutputMode(String outputMode) {
100         this.outputMode = outputMode;
101     }
102 
103     /***
104      * Sets whether pretty printing mode is turned on. The default is off so that whitespace is preserved
105      */
106     public void setPrettyPrint(boolean prettyPrint) {
107         this.prettyPrint = prettyPrint;
108     }
109 
110     /***
111      * Sets the XML encoding mode, which defaults to UTF-8
112      */
113     public void setEncoding(String encoding) {
114         this.encoding = encoding;
115     }
116 
117     /***
118      * Returns the var.
119      * @return String
120      */
121     public String getVar() {
122         return var;
123     }
124 
125     /***
126      * Sets the var.
127      * @param var The var to set
128      */
129     public void setVar(String var) {
130         this.var = var;
131     }
132 
133     /***
134      * Writes the body fo this tag to the given Writer
135      */
136     protected void writeBody(Writer writer) throws SAXException, JellyTagException {
137 
138         XMLOutput newOutput = createXMLOutput(writer);
139         try {
140             // we need to avoid multiple start/end document events
141             newOutput.setContentHandler(
142                 new SafeContentHandler(newOutput.getContentHandler())
143             );
144             newOutput.startDocument();
145             invokeBody(newOutput);
146             newOutput.endDocument();
147         }
148         finally {
149             try { newOutput.close(); } catch (IOException e) {}
150         }
151     }
152 
153     /***
154      * A Factory method to create a new XMLOutput from the given Writer.
155      */
156     protected XMLOutput createXMLOutput(Writer writer) {
157 
158         OutputFormat format = null;
159         if (prettyPrint) {
160             format = OutputFormat.createPrettyPrint();
161         }
162         else {
163             format = new OutputFormat();
164         }
165         if ( encoding != null ) {
166             format.setEncoding( encoding );
167         }
168         if ( omitXmlDeclaration ) {
169             format.setSuppressDeclaration(true);
170         }
171 
172         boolean isHtml = outputMode != null && outputMode.equalsIgnoreCase( "html" );
173         final XMLWriter xmlWriter = (isHtml)
174             ? new HTMLWriter(writer, format)
175             : new XMLWriter(writer, format);
176 
177         xmlWriter.setEscapeText(isEscapeText());
178 
179         XMLOutput answer = new XMLOutput() {
180             public void close() throws IOException {
181                 xmlWriter.close();
182             }
183         };
184         answer.setContentHandler(xmlWriter);
185         answer.setLexicalHandler(xmlWriter);
186         return answer;
187     }
188 }