001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jsp;
031:
032: import com.caucho.server.connection.AbstractResponseStream;
033: import com.caucho.util.L10N;
034:
035: import javax.servlet.jsp.JspWriter;
036: import java.io.IOException;
037: import java.util.logging.Level;
038:
039: /**
040: * A buffered JSP writer encapsulating a Writer.
041: */
042: public class JspWriterAdapter extends AbstractBodyContent {
043: private static final L10N L = new L10N(JspWriterAdapter.class);
044:
045: // the parent writer
046: private JspWriter _parent;
047:
048: // the underlying writer
049: private AbstractResponseStream _out;
050:
051: // the page context
052: private PageContextImpl _pageContext;
053:
054: private boolean _isClosed;
055:
056: /**
057: * Creates a new JspWriterAdapter
058: */
059: JspWriterAdapter() {
060: }
061:
062: /**
063: * Initialize the JSP writer
064: *
065: * @param os the underlying stream
066: */
067: void init(PageContextImpl pageContext) {
068: _pageContext = pageContext;
069: _out = null;
070: _isClosed = false;
071: }
072:
073: /**
074: * Initialize the JSP writer
075: *
076: * @param os the underlying stream
077: */
078: void init(JspWriter parent, AbstractResponseStream out) {
079: _parent = parent;
080: _out = out;
081: _isClosed = false;
082: }
083:
084: /**
085: * Writes a character array to the writer.
086: *
087: * @param buf the buffer to write.
088: * @param off the offset into the buffer
089: * @param len the number of characters to write
090: */
091: final public void write(char[] buf, int offset, int length)
092: throws IOException {
093: if (_isClosed)
094: throw new IOException(L
095: .l("write() forbidden after writer is closed"));
096:
097: _out.print(buf, offset, length);
098: }
099:
100: /**
101: * Writes a character to the output.
102: *
103: * @param buf the buffer to write.
104: */
105: final public void write(int ch) throws IOException {
106: if (_isClosed) {
107: if (Character.isWhitespace(ch))
108: return;
109:
110: throw new IOException(L
111: .l("write() forbidden after writer is closed"));
112: }
113:
114: _out.print(ch);
115: }
116:
117: /**
118: * Prints the newline.
119: */
120: final public void println() throws IOException {
121: if (_isClosed) {
122: throw new IOException(L
123: .l("write() forbidden after writer is closed"));
124: }
125:
126: _out.print('\n');
127: }
128:
129: /**
130: * Writes a subsection of a string to the output.
131: */
132: final public void write(String s, int off, int len)
133: throws IOException {
134: if (_isClosed)
135: throw new IOException(L
136: .l("write() forbidden after writer is closed"));
137:
138: char[] writeBuffer = _out.getCharBuffer();
139: int size = writeBuffer.length;
140: int writeLength = _out.getCharOffset();
141: int end = off + len;
142:
143: while (off < end) {
144: int sublen = end - off;
145:
146: if (size - writeLength < sublen) {
147: if (size == writeLength) {
148: writeBuffer = _out.nextCharBuffer(writeLength);
149: writeLength = 0;
150:
151: if (size < sublen)
152: sublen = size;
153: } else
154: sublen = size - writeLength;
155: }
156:
157: int tail = off + sublen;
158: s.getChars(off, tail, writeBuffer, writeLength);
159:
160: off = tail;
161: writeLength += sublen;
162: }
163:
164: _out.setCharOffset(writeLength);
165: }
166:
167: /**
168: * Returns the buffer size of the writer.
169: */
170: public int getBufferSize() {
171: return _out.getBufferSize();
172: }
173:
174: /**
175: * Returns the remaining bytes in the buffer.
176: */
177: public int getRemaining() {
178: return _out.getRemaining();
179: }
180:
181: public void clear() throws IOException {
182: if (_isClosed)
183: throw new IOException(L
184: .l("clear() forbidden after writer is closed"));
185: /*
186: else if (_out.isCommitted()) {
187: // jsp/0502
188: throw new IOException(L.l("clear() forbidden after data is committed"));
189: }
190: */
191:
192: _out.clear();
193: // clearBuffer();
194: }
195:
196: public void clearBuffer() throws IOException {
197: if (_isClosed)
198: return;
199:
200: _out.clearBuffer();
201: }
202:
203: public void flushBuffer() throws IOException {
204: if (_isClosed)
205: throw new IOException(
206: L
207: .l("flushBuffer() forbidden after writer is closed"));
208:
209: _out.flushBuffer();
210: }
211:
212: /**
213: * Flushes the output stream.
214: */
215: public void flush() throws IOException {
216: if (_isClosed)
217: throw new IOException(L
218: .l("flush() forbidden after writer is closed"));
219:
220: _out.flushChar();
221: }
222:
223: /**
224: * Pops the enclosing writer.
225: */
226: AbstractJspWriter popWriter() {
227: try {
228: close();
229: } catch (Throwable e) {
230: log.log(Level.FINER, e.toString(), e);
231: }
232:
233: return super .popWriter();
234: }
235:
236: final public void close() throws IOException {
237: _isClosed = true;
238:
239: _out = null;
240: _parent = null;
241: _pageContext = null;
242: }
243: }
|