001: /*
002: * Copyright 2002,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jelly.tags.core;
017:
018: import java.io.FileNotFoundException;
019: import java.io.FileOutputStream;
020: import java.io.IOException;
021: import java.io.OutputStreamWriter;
022: import java.io.StringWriter;
023: import java.io.UnsupportedEncodingException;
024: import java.io.Writer;
025:
026: import org.apache.commons.jelly.JellyTagException;
027: import org.apache.commons.jelly.TagSupport;
028: import org.apache.commons.jelly.XMLOutput;
029: import org.apache.commons.jelly.util.SafeContentHandler;
030: import org.dom4j.io.HTMLWriter;
031: import org.dom4j.io.OutputFormat;
032: import org.dom4j.io.XMLWriter;
033: import org.xml.sax.SAXException;
034:
035: /**
036: * A tag that pipes its body to a file denoted by the name attribute or to an in memory String
037: * which is then output to a variable denoted by the var variable.
038: *
039: * @author <a href="mailto:vinayc@apache.org">Vinay Chandran</a>
040: */
041: public class FileTag extends TagSupport {
042: private boolean doAppend = false;
043: private String var;
044: private String name;
045: private boolean omitXmlDeclaration = false;
046: private String outputMode = "xml";
047: private boolean prettyPrint;
048: private String encoding;
049:
050: public FileTag() {
051: }
052:
053: // Tag interface
054: //-------------------------------------------------------------------------
055: public void doTag(final XMLOutput output) throws JellyTagException {
056: try {
057: if (name != null) {
058: String encoding = (this .encoding != null) ? this .encoding
059: : "UTF-8";
060: Writer writer = new OutputStreamWriter(
061: new FileOutputStream(name, doAppend), encoding);
062: writeBody(writer);
063: } else if (var != null) {
064: StringWriter writer = new StringWriter();
065: writeBody(writer);
066: String result = writer.toString();
067: Object varValue = context.getVariable(var);
068: // if we're appending, and var is an instance of string, append it.
069: if (doAppend && varValue instanceof String) {
070: context.setVariable(var, varValue + result);
071: } else {
072: context.setVariable(var, result);
073: }
074: } else {
075: throw new JellyTagException(
076: "This tag must have either the 'name' or the 'var' variables defined");
077: }
078: } catch (FileNotFoundException e) {
079: throw new JellyTagException(e);
080: } catch (UnsupportedEncodingException e) {
081: throw new JellyTagException(e);
082: } catch (SAXException e) {
083: throw new JellyTagException("could not write file", e);
084: }
085: }
086:
087: // Properties
088: //-------------------------------------------------------------------------
089:
090: /**
091: * Sets the file name for the output
092: */
093: public void setName(String name) {
094: this .name = name;
095: }
096:
097: /**
098: * Sets whether the XML declaration should be output or not
099: */
100: public void setOmitXmlDeclaration(boolean omitXmlDeclaration) {
101: this .omitXmlDeclaration = omitXmlDeclaration;
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: * Returns the var.
135: * @return String
136: */
137: public String getVar() {
138: return var;
139: }
140:
141: /**
142: * Sets the var.
143: * @param var The var to set
144: */
145: public void setVar(String var) {
146: this .var = var;
147: }
148:
149: /**
150: * Writes the body fo this tag to the given Writer
151: */
152: protected void writeBody(Writer writer) throws SAXException,
153: JellyTagException {
154:
155: XMLOutput newOutput = createXMLOutput(writer);
156: try {
157: // we need to avoid multiple start/end document events
158: newOutput.setContentHandler(new SafeContentHandler(
159: newOutput.getContentHandler()));
160: newOutput.startDocument();
161: invokeBody(newOutput);
162: newOutput.endDocument();
163: } finally {
164: try {
165: newOutput.close();
166: } catch (IOException e) {
167: }
168: }
169: }
170:
171: /**
172: * A Factory method to create a new XMLOutput from the given Writer.
173: */
174: protected XMLOutput createXMLOutput(Writer writer) {
175:
176: OutputFormat format = null;
177: if (prettyPrint) {
178: format = OutputFormat.createPrettyPrint();
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
190: && outputMode.equalsIgnoreCase("html");
191: final XMLWriter xmlWriter = (isHtml) ? new HTMLWriter(writer,
192: format) : 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: }
|