001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: // Sep 14, 2000:
019: // Fixed serializer to report IO exception directly, instead at
020: // the end of document processing.
021: // Reported by Patrick Higgins <phiggins@transzap.com>
022:
023: package org.apache.xml.serialize;
024:
025: import java.io.Writer;
026: import java.io.StringWriter;
027: import java.io.IOException;
028:
029: /**
030: * The printer is responsible for sending text to the output stream
031: * or writer. This class performs direct writing for efficiency.
032: * {@link IndentPrinter} supports indentation and line wrapping by
033: * extending this class.
034: *
035: * @deprecated This class was deprecated in Xerces 2.9.0. It is recommended
036: * that new applications use the DOM Level 3 LSSerializer or JAXP's Transformation
037: * API for XML (TrAX) for serializing XML. See the Xerces documentation for more
038: * information.
039: * @version $Revision: 476047 $ $Date: 2006-11-16 23:27:45 -0500 (Thu, 16 Nov 2006) $
040: * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
041: */
042: public class Printer {
043:
044: /**
045: * The output format associated with this serializer. This will never
046: * be a null reference. If no format was passed to the constructor,
047: * the default one for this document type will be used. The format
048: * object is never changed by the serializer.
049: */
050: protected final OutputFormat _format;
051:
052: /**
053: * The writer to which the document is written.
054: */
055: protected Writer _writer;
056:
057: /**
058: * The DTD writer. When we switch to DTD mode, all output is
059: * accumulated in this DTD writer. When we switch out of it,
060: * the output is obtained as a string. Must not be reset to
061: * null until we're done with the document.
062: */
063: protected StringWriter _dtdWriter;
064:
065: /**
066: * Holds a reference to the document writer while we are
067: * in DTD mode.
068: */
069: protected Writer _docWriter;
070:
071: /**
072: * Holds the exception thrown by the serializer. Exceptions do not cause
073: * the serializer to quit, but are held and one is thrown at the end.
074: */
075: protected IOException _exception;
076:
077: /**
078: * The size of the output buffer.
079: */
080: private static final int BufferSize = 4096;
081:
082: /**
083: * Output buffer.
084: */
085: private final char[] _buffer = new char[BufferSize];
086:
087: /**
088: * Position within the output buffer.
089: */
090: private int _pos = 0;
091:
092: public Printer(Writer writer, OutputFormat format) {
093: _writer = writer;
094: _format = format;
095: _exception = null;
096: _dtdWriter = null;
097: _docWriter = null;
098: _pos = 0;
099: }
100:
101: public IOException getException() {
102: return _exception;
103: }
104:
105: /**
106: * Called by any of the DTD handlers to enter DTD mode.
107: * Once entered, all output will be accumulated in a string
108: * that can be printed as part of the document's DTD.
109: * This method may be called any number of time but will only
110: * have affect the first time it's called. To exist DTD state
111: * and get the accumulated DTD, call {@link #leaveDTD}.
112: */
113: public void enterDTD() throws IOException {
114: // Can only enter DTD state once. Once we're out of DTD
115: // state, can no longer re-enter it.
116: if (_dtdWriter == null) {
117: flushLine(false);
118:
119: _dtdWriter = new StringWriter();
120: _docWriter = _writer;
121: _writer = _dtdWriter;
122: }
123: }
124:
125: /**
126: * Called by the root element to leave DTD mode and if any
127: * DTD parts were printer, will return a string with their
128: * textual content.
129: */
130: public String leaveDTD() throws IOException {
131: // Only works if we're going out of DTD mode.
132: if (_writer == _dtdWriter) {
133: flushLine(false);
134:
135: _writer = _docWriter;
136: return _dtdWriter.toString();
137: }
138: return null;
139: }
140:
141: public void printText(String text) throws IOException {
142: try {
143: int length = text.length();
144: for (int i = 0; i < length; ++i) {
145: if (_pos == BufferSize) {
146: _writer.write(_buffer);
147: _pos = 0;
148: }
149: _buffer[_pos] = text.charAt(i);
150: ++_pos;
151: }
152: } catch (IOException except) {
153: // We don't throw an exception, but hold it
154: // until the end of the document.
155: if (_exception == null)
156: _exception = except;
157: throw except;
158: }
159: }
160:
161: public void printText(StringBuffer text) throws IOException {
162: try {
163: int length = text.length();
164: for (int i = 0; i < length; ++i) {
165: if (_pos == BufferSize) {
166: _writer.write(_buffer);
167: _pos = 0;
168: }
169: _buffer[_pos] = text.charAt(i);
170: ++_pos;
171: }
172: } catch (IOException except) {
173: // We don't throw an exception, but hold it
174: // until the end of the document.
175: if (_exception == null)
176: _exception = except;
177: throw except;
178: }
179: }
180:
181: public void printText(char[] chars, int start, int length)
182: throws IOException {
183: try {
184: while (length-- > 0) {
185: if (_pos == BufferSize) {
186: _writer.write(_buffer);
187: _pos = 0;
188: }
189: _buffer[_pos] = chars[start];
190: ++start;
191: ++_pos;
192: }
193: } catch (IOException except) {
194: // We don't throw an exception, but hold it
195: // until the end of the document.
196: if (_exception == null)
197: _exception = except;
198: throw except;
199: }
200: }
201:
202: public void printText(char ch) throws IOException {
203: try {
204: if (_pos == BufferSize) {
205: _writer.write(_buffer);
206: _pos = 0;
207: }
208: _buffer[_pos] = ch;
209: ++_pos;
210: } catch (IOException except) {
211: // We don't throw an exception, but hold it
212: // until the end of the document.
213: if (_exception == null)
214: _exception = except;
215: throw except;
216: }
217: }
218:
219: public void printSpace() throws IOException {
220: try {
221: if (_pos == BufferSize) {
222: _writer.write(_buffer);
223: _pos = 0;
224: }
225: _buffer[_pos] = ' ';
226: ++_pos;
227: } catch (IOException except) {
228: // We don't throw an exception, but hold it
229: // until the end of the document.
230: if (_exception == null)
231: _exception = except;
232: throw except;
233: }
234: }
235:
236: public void breakLine() throws IOException {
237: try {
238: if (_pos == BufferSize) {
239: _writer.write(_buffer);
240: _pos = 0;
241: }
242: _buffer[_pos] = '\n';
243: ++_pos;
244: } catch (IOException except) {
245: // We don't throw an exception, but hold it
246: // until the end of the document.
247: if (_exception == null)
248: _exception = except;
249: throw except;
250: }
251: }
252:
253: public void breakLine(boolean preserveSpace) throws IOException {
254: breakLine();
255: }
256:
257: public void flushLine(boolean preserveSpace) throws IOException {
258: // Write anything left in the buffer into the writer.
259: try {
260: _writer.write(_buffer, 0, _pos);
261: } catch (IOException except) {
262: // We don't throw an exception, but hold it
263: // until the end of the document.
264: if (_exception == null)
265: _exception = except;
266: }
267: _pos = 0;
268: }
269:
270: /**
271: * Flush the output stream. Must be called when done printing
272: * the document, otherwise some text might be buffered.
273: */
274: public void flush() throws IOException {
275: try {
276: _writer.write(_buffer, 0, _pos);
277: _writer.flush();
278: } catch (IOException except) {
279: // We don't throw an exception, but hold it
280: // until the end of the document.
281: if (_exception == null)
282: _exception = except;
283: throw except;
284: }
285: _pos = 0;
286: }
287:
288: public void indent() {
289: // NOOP
290: }
291:
292: public void unindent() {
293: // NOOP
294: }
295:
296: public int getNextIndent() {
297: return 0;
298: }
299:
300: public void setNextIndent(int indent) {
301: }
302:
303: public void setThisIndent(int indent) {
304: }
305:
306: }
|