001: package groovy.xml.streamingmarkupsupport;
002:
003: /*
004:
005: Copyright 2004 (C) John Wilson. All Rights Reserved.
006:
007: Redistribution and use of this software and associated documentation
008: ("Software"), with or without modification, are permitted provided
009: that the following conditions are met:
010:
011: 1. Redistributions of source code must retain copyright
012: statements and notices. Redistributions must also contain a
013: copy of this document.
014:
015: 2. Redistributions in binary form must reproduce the
016: above copyright notice, this list of conditions and the
017: following disclaimer in the documentation and/or other
018: materials provided with the distribution.
019:
020: 3. The name "groovy" must not be used to endorse or promote
021: products derived from this Software without prior written
022: permission of The Codehaus. For written permission,
023: please contact info@codehaus.org.
024:
025: 4. Products derived from this Software may not be called "groovy"
026: nor may "groovy" appear in their names without prior written
027: permission of The Codehaus. "groovy" is a registered
028: trademark of The Codehaus.
029:
030: 5. Due credit should be given to The Codehaus -
031: http://groovy.codehaus.org/
032:
033: THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
034: ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
035: NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
036: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
037: THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
038: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
039: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
040: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
041: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
042: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
043: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
044: OF THE POSSIBILITY OF SUCH DAMAGE.
045:
046: */
047:
048: import java.io.IOException;
049: import java.io.OutputStreamWriter;
050: import java.io.Writer;
051: import java.nio.charset.Charset;
052: import java.nio.charset.CharsetEncoder;
053:
054: public class StreamingMarkupWriter extends Writer {
055: protected final Writer writer;
056: protected final String encoding;
057: protected final CharsetEncoder encoder;
058: private final Writer bodyWriter = new Writer() {
059: /* (non-Javadoc)
060: * @see java.io.Writer#close()
061: */
062: public void close() throws IOException {
063: StreamingMarkupWriter.this .close();
064: }
065:
066: /* (non-Javadoc)
067: * @see java.io.Writer#flush()
068: */
069: public void flush() throws IOException {
070: StreamingMarkupWriter.this .flush();
071: }
072:
073: /* (non-Javadoc)
074: * @see java.io.Writer#write(int)
075: */
076: public void write(final int c) throws IOException {
077: if (!StreamingMarkupWriter.this .encoder.canEncode((char) c)) {
078: StreamingMarkupWriter.this .writer.write("&#x");
079: StreamingMarkupWriter.this .writer.write(Integer
080: .toHexString(c));
081: StreamingMarkupWriter.this .writer.write(';');
082: } else if (c == '<') {
083: StreamingMarkupWriter.this .writer.write("<");
084: } else if (c == '>') {
085: StreamingMarkupWriter.this .writer.write(">");
086: } else if (c == '&') {
087: StreamingMarkupWriter.this .writer.write("&");
088: } else {
089: StreamingMarkupWriter.this .writer.write(c);
090: }
091: }
092:
093: /* (non-Javadoc)
094: * @see java.io.Writer#write(char[], int, int)
095: */
096: public void write(final char[] cbuf, int off, int len)
097: throws IOException {
098: while (len-- > 0) {
099: write(cbuf[off++]);
100: }
101: }
102:
103: public Writer attributeValue() {
104: return StreamingMarkupWriter.this .attributeWriter;
105: }
106:
107: public Writer bodyText() {
108: return bodyWriter;
109: }
110:
111: public Writer unescaped() {
112: return StreamingMarkupWriter.this ;
113: }
114: };
115:
116: private final Writer attributeWriter = new Writer() {
117: /* (non-Javadoc)
118: * @see java.io.Writer#close()
119: */
120: public void close() throws IOException {
121: StreamingMarkupWriter.this .close();
122: }
123:
124: /* (non-Javadoc)
125: * @see java.io.Writer#flush()
126: */
127: public void flush() throws IOException {
128: StreamingMarkupWriter.this .flush();
129: }
130:
131: /* (non-Javadoc)
132: * @see java.io.Writer#write(int)
133: */
134: public void write(final int c) throws IOException {
135: if (c == '\'') {
136: StreamingMarkupWriter.this .writer.write("'");
137: } else {
138: StreamingMarkupWriter.this .bodyWriter.write(c);
139: }
140: }
141:
142: /* (non-Javadoc)
143: * @see java.io.Writer#write(char[], int, int)
144: */
145: public void write(final char[] cbuf, int off, int len)
146: throws IOException {
147: while (len-- > 0) {
148: write(cbuf[off++]);
149: }
150: }
151:
152: public Writer attributeValue() {
153: return attributeWriter;
154: }
155:
156: public Writer bodyText() {
157: return StreamingMarkupWriter.this .bodyWriter;
158: }
159:
160: public Writer unescaped() {
161: return StreamingMarkupWriter.this ;
162: }
163: };
164:
165: public StreamingMarkupWriter(final Writer writer,
166: final String encoding) {
167: this .writer = writer;
168:
169: if (encoding != null) {
170: this .encoding = encoding;
171: } else if (writer instanceof OutputStreamWriter) {
172: this .encoding = ((OutputStreamWriter) writer).getEncoding();
173: } else {
174: this .encoding = "US-ASCII";
175: }
176:
177: this .encoder = Charset.forName(this .encoding).newEncoder();
178: }
179:
180: public StreamingMarkupWriter(final Writer writer) {
181: this (writer, null);
182: }
183:
184: /* (non-Javadoc)
185: * @see java.io.Writer#close()
186: */
187: public void close() throws IOException {
188: this .writer.close();
189: }
190:
191: /* (non-Javadoc)
192: * @see java.io.Writer#flush()
193: */
194: public void flush() throws IOException {
195: this .writer.flush();
196: }
197:
198: /* (non-Javadoc)
199: * @see java.io.Writer#write(int)
200: */
201: public void write(final int c) throws IOException {
202: if (!this .encoder.canEncode((char) c)) {
203: this .writer.write("&#x");
204: this .writer.write(Integer.toHexString(c));
205: this .writer.write(';');
206: } else {
207: this .writer.write(c);
208: }
209: }
210:
211: /* (non-Javadoc)
212: * @see java.io.Writer#write(char[], int, int)
213: */
214: public void write(final char[] cbuf, int off, int len)
215: throws IOException {
216: while (len-- > 0) {
217: write(cbuf[off++]);
218: }
219: }
220:
221: public Writer attributeValue() {
222: return this .attributeWriter;
223: }
224:
225: public Writer bodyText() {
226: return this .bodyWriter;
227: }
228:
229: public Writer unescaped() {
230: return this ;
231: }
232:
233: public String getEncoding() {
234: return this.encoding;
235: }
236: }
|