001
014
015 package com.liferay.portal.kernel.servlet;
016
017 import com.liferay.portal.kernel.io.DummyOutputStream;
018 import com.liferay.portal.kernel.io.DummyWriter;
019 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
020 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
021 import com.liferay.portal.kernel.nio.charset.CharsetDecoderUtil;
022 import com.liferay.portal.kernel.nio.charset.CharsetEncoderUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
026
027 import java.io.IOException;
028 import java.io.PrintWriter;
029
030 import java.nio.ByteBuffer;
031 import java.nio.CharBuffer;
032
033 import javax.servlet.ServletOutputStream;
034 import javax.servlet.http.HttpServletResponse;
035
036
039 public class BufferCacheServletResponse extends MetaInfoCacheServletResponse {
040
041 public BufferCacheServletResponse(HttpServletResponse response) {
042 super(response);
043 }
044
045
051 @Override
052 public int getBufferSize() {
053 if (_byteBuffer != null) {
054 return _byteBuffer.limit();
055 }
056
057 if (_charBuffer != null) {
058 ByteBuffer byteBuffer = CharsetEncoderUtil.encode(
059 getCharacterEncoding(), _charBuffer.duplicate());
060
061 return byteBuffer.limit();
062 }
063
064 try {
065 _flushInternalBuffer();
066 }
067 catch (IOException ioe) {
068 throw new RuntimeException(ioe);
069 }
070
071 if (_unsyncByteArrayOutputStream != null) {
072 return _unsyncByteArrayOutputStream.size();
073 }
074
075 if (_unsyncStringWriter != null) {
076 String content = _unsyncStringWriter.toString();
077
078 ByteBuffer byteBuffer = CharsetEncoderUtil.encode(
079 getCharacterEncoding(), content);
080
081 return byteBuffer.limit();
082 }
083
084 return 0;
085 }
086
087
094 public ByteBuffer getByteBuffer() throws IOException {
095 if (_byteBuffer != null) {
096 return _byteBuffer;
097 }
098
099 if (_charBuffer != null) {
100 return CharsetEncoderUtil.encode(
101 getCharacterEncoding(), _charBuffer.duplicate());
102 }
103
104 _flushInternalBuffer();
105
106 if (_unsyncByteArrayOutputStream != null) {
107 return _unsyncByteArrayOutputStream.unsafeGetByteBuffer();
108 }
109
110 if (_unsyncStringWriter != null) {
111 String content = _unsyncStringWriter.toString();
112
113 return CharsetEncoderUtil.encode(getCharacterEncoding(), content);
114 }
115
116 return _emptyByteBuffer;
117 }
118
119
128 public CharBuffer getCharBuffer() throws IOException {
129 if (_charBuffer != null) {
130 return _charBuffer;
131 }
132
133 if (_byteBuffer != null) {
134 return CharsetDecoderUtil.decode(
135 getCharacterEncoding(), _byteBuffer.duplicate());
136 }
137
138 _flushInternalBuffer();
139
140 if (_unsyncStringWriter != null) {
141 return CharBuffer.wrap(_unsyncStringWriter.toString());
142 }
143
144 if (_unsyncByteArrayOutputStream != null) {
145 ByteBuffer byteBuffer =
146 _unsyncByteArrayOutputStream.unsafeGetByteBuffer();
147
148 return CharsetDecoderUtil.decode(
149 getCharacterEncoding(), byteBuffer);
150 }
151
152 return _emptyCharBuffer;
153 }
154
155 @Override
156 public ServletOutputStream getOutputStream() {
157 if (calledGetWriter) {
158 throw new IllegalStateException(
159 "Unable to obtain OutputStream because Writer is already in " +
160 "use");
161 }
162
163 if (_servletOutputStream != null) {
164 return _servletOutputStream;
165 }
166
167 resetBuffer(true);
168
169 _unsyncByteArrayOutputStream = new UnsyncByteArrayOutputStream();
170
171 _servletOutputStream = new ServletOutputStreamAdapter(
172 _unsyncByteArrayOutputStream);
173
174 calledGetOutputStream = true;
175
176 return _servletOutputStream;
177 }
178
179
182 public String getString() throws IOException {
183 if (_charBuffer != null) {
184 return _charBuffer.toString();
185 }
186
187 if (_byteBuffer != null) {
188 CharBuffer charBuffer = CharsetDecoderUtil.decode(
189 getCharacterEncoding(), _byteBuffer.duplicate());
190
191 return charBuffer.toString();
192 }
193
194 _flushInternalBuffer();
195
196 if (_unsyncStringWriter != null) {
197 return _unsyncStringWriter.toString();
198 }
199
200 if (_unsyncByteArrayOutputStream != null) {
201 ByteBuffer byteBuffer =
202 _unsyncByteArrayOutputStream.unsafeGetByteBuffer();
203
204 CharBuffer charBuffer = CharsetDecoderUtil.decode(
205 getCharacterEncoding(), byteBuffer);
206
207 return charBuffer.toString();
208 }
209
210 return StringPool.BLANK;
211 }
212
213
216 public StringBundler getStringBundler() throws IOException {
217 if (_charBuffer != null) {
218 StringBundler sb = new StringBundler(1);
219
220 sb.append(_charBuffer.toString());
221
222 return sb;
223 }
224
225 if (_byteBuffer != null) {
226 CharBuffer charBuffer = CharsetDecoderUtil.decode(
227 getCharacterEncoding(), _byteBuffer.duplicate());
228
229 StringBundler sb = new StringBundler(1);
230
231 sb.append(charBuffer.toString());
232
233 return sb;
234 }
235
236 _flushInternalBuffer();
237
238 if (_unsyncStringWriter != null) {
239 return _unsyncStringWriter.getStringBundler();
240 }
241
242 if (_unsyncByteArrayOutputStream != null) {
243 ByteBuffer byteBuffer =
244 _unsyncByteArrayOutputStream.unsafeGetByteBuffer();
245
246 CharBuffer charBuffer = CharsetDecoderUtil.decode(
247 getCharacterEncoding(), byteBuffer);
248
249 StringBundler sb = new StringBundler(1);
250
251 sb.append(charBuffer.toString());
252
253 return sb;
254 }
255
256 return new StringBundler(1);
257 }
258
259 @Override
260 public PrintWriter getWriter() {
261 if (calledGetOutputStream) {
262 throw new IllegalStateException(
263 "Cannot obtain Writer because OutputStream is already in use");
264 }
265
266 if (_printWriter != null) {
267 return _printWriter;
268 }
269
270 resetBuffer(true);
271
272 _unsyncStringWriter = new UnsyncStringWriter();
273
274 _printWriter = UnsyncPrintWriterPool.borrow(_unsyncStringWriter);
275
276 calledGetWriter = true;
277
278 return _printWriter;
279 }
280
281 public boolean isByteMode() {
282 if ((_byteBuffer != null) || (_unsyncByteArrayOutputStream != null)) {
283 return true;
284 }
285
286 return false;
287 }
288
289 public boolean isCharMode() {
290 if ((_charBuffer != null) || (_unsyncStringWriter != null)) {
291 return true;
292 }
293
294 return false;
295 }
296
297 public void outputBuffer() throws IOException {
298 _flushInternalBuffer();
299
300 HttpServletResponse response = (HttpServletResponse)getResponse();
301
302 if ((_byteBuffer != null) || calledGetOutputStream) {
303 ServletResponseUtil.write(response, getByteBuffer());
304 }
305 else if ((_charBuffer != null) || calledGetWriter) {
306 ServletResponseUtil.write(response, getCharBuffer());
307 }
308 }
309
310 @Override
311 public void setBufferSize(int bufferSize) {
312 if (isCommitted()) {
313 throw new IllegalStateException("Set buffer size after commit");
314 }
315
316
317
318
319 }
320
321 public void setByteBuffer(ByteBuffer byteBuffer) {
322 resetBuffer(true);
323
324 _byteBuffer = byteBuffer;
325
326 if (byteBuffer != null) {
327 _servletOutputStream = new ServletOutputStreamAdapter(
328 new DummyOutputStream());
329
330 calledGetOutputStream = true;
331 }
332 }
333
334 public void setCharBuffer(CharBuffer charBuffer) {
335 resetBuffer(true);
336
337 _charBuffer = charBuffer;
338
339 if (charBuffer != null) {
340 _printWriter = UnsyncPrintWriterPool.borrow(new DummyWriter());
341
342 calledGetWriter = true;
343 }
344 }
345
346 @Override
347 public void setContentLength(int contentLength) {
348
349
350
351
352 }
353
354 public void setString(String string) {
355 setCharBuffer(CharBuffer.wrap(string));
356 }
357
358 @Override
359 protected void resetBuffer(boolean nullOutReferences) {
360 if (nullOutReferences) {
361 calledGetOutputStream = false;
362 calledGetWriter = false;
363
364 _printWriter = null;
365 _servletOutputStream = null;
366 _unsyncByteArrayOutputStream = null;
367 _unsyncStringWriter = null;
368 }
369 else {
370 if (_unsyncByteArrayOutputStream != null) {
371 _unsyncByteArrayOutputStream.reset();
372 }
373
374 if (_unsyncStringWriter != null) {
375 _unsyncStringWriter.reset();
376 }
377
378 if (_byteBuffer != null) {
379 _servletOutputStream = null;
380
381 calledGetOutputStream = false;
382 }
383
384 if (_charBuffer != null) {
385 _printWriter = null;
386
387 calledGetWriter = false;
388 }
389 }
390
391 _byteBuffer = null;
392 _charBuffer = null;
393 }
394
395 private void _flushInternalBuffer() throws IOException {
396 if (calledGetOutputStream) {
397 _servletOutputStream.flush();
398 }
399 else if (calledGetWriter) {
400 _printWriter.flush();
401 }
402 }
403
404 private static ByteBuffer _emptyByteBuffer = ByteBuffer.allocate(0);
405 private static CharBuffer _emptyCharBuffer = CharBuffer.allocate(0);
406
407 private ByteBuffer _byteBuffer;
408 private CharBuffer _charBuffer;
409 private PrintWriter _printWriter;
410 private ServletOutputStream _servletOutputStream;
411 private UnsyncByteArrayOutputStream _unsyncByteArrayOutputStream;
412 private UnsyncStringWriter _unsyncStringWriter;
413
414 }