1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
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
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 }