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 "Cannot obtain OutputStream because Writer is already in use");
160 }
161
162 if (_servletOutputStream != null) {
163 return _servletOutputStream;
164 }
165
166 resetBuffer(true);
167
168 _unsyncByteArrayOutputStream = new UnsyncByteArrayOutputStream();
169
170 _servletOutputStream = new ServletOutputStreamAdapter(
171 _unsyncByteArrayOutputStream);
172
173 calledGetOutputStream = true;
174
175 return _servletOutputStream;
176 }
177
178
181 public String getString() throws IOException {
182 if (_charBuffer != null) {
183 return _charBuffer.toString();
184 }
185
186 if (_byteBuffer != null) {
187 CharBuffer charBuffer = CharsetDecoderUtil.decode(
188 getCharacterEncoding(), _byteBuffer.duplicate());
189
190 return charBuffer.toString();
191 }
192
193 _flushInternalBuffer();
194
195 if (_unsyncStringWriter != null) {
196 return _unsyncStringWriter.toString();
197 }
198
199 if (_unsyncByteArrayOutputStream != null) {
200 ByteBuffer byteBuffer =
201 _unsyncByteArrayOutputStream.unsafeGetByteBuffer();
202
203 CharBuffer charBuffer = CharsetDecoderUtil.decode(
204 getCharacterEncoding(), byteBuffer);
205
206 return charBuffer.toString();
207 }
208
209 return StringPool.BLANK;
210 }
211
212
215 public StringBundler getStringBundler() throws IOException {
216 if (_charBuffer != null) {
217 StringBundler sb = new StringBundler(1);
218
219 sb.append(_charBuffer.toString());
220
221 return sb;
222 }
223
224 if (_byteBuffer != null) {
225 CharBuffer charBuffer = CharsetDecoderUtil.decode(
226 getCharacterEncoding(), _byteBuffer.duplicate());
227
228 StringBundler sb = new StringBundler(1);
229
230 sb.append(charBuffer.toString());
231
232 return sb;
233 }
234
235 _flushInternalBuffer();
236
237 if (_unsyncStringWriter != null) {
238 return _unsyncStringWriter.getStringBundler();
239 }
240
241 if (_unsyncByteArrayOutputStream != null) {
242 ByteBuffer byteBuffer =
243 _unsyncByteArrayOutputStream.unsafeGetByteBuffer();
244
245 CharBuffer charBuffer = CharsetDecoderUtil.decode(
246 getCharacterEncoding(), byteBuffer);
247
248 StringBundler sb = new StringBundler(1);
249
250 sb.append(charBuffer.toString());
251
252 return sb;
253 }
254
255 return new StringBundler(1);
256 }
257
258 @Override
259 public PrintWriter getWriter() {
260 if (calledGetOutputStream) {
261 throw new IllegalStateException(
262 "Cannot obtain Writer because OutputStream is already in use");
263 }
264
265 if (_printWriter != null) {
266 return _printWriter;
267 }
268
269 resetBuffer(true);
270
271 _unsyncStringWriter = new UnsyncStringWriter();
272
273 _printWriter = UnsyncPrintWriterPool.borrow(_unsyncStringWriter);
274
275 calledGetWriter = true;
276
277 return _printWriter;
278 }
279
280 public boolean isByteMode() {
281 if ((_byteBuffer != null) || (_unsyncByteArrayOutputStream != null)) {
282 return true;
283 }
284
285 return false;
286 }
287
288 public boolean isCharMode() {
289 if ((_charBuffer != null) || (_unsyncStringWriter != null)) {
290 return true;
291 }
292
293 return false;
294 }
295
296 public void outputBuffer() throws IOException {
297 _flushInternalBuffer();
298
299 HttpServletResponse response = (HttpServletResponse)getResponse();
300
301 if ((_byteBuffer != null) || calledGetOutputStream) {
302 ServletResponseUtil.write(response, getByteBuffer());
303 }
304 else if ((_charBuffer != null) || calledGetWriter) {
305 ServletResponseUtil.write(response, getCharBuffer());
306 }
307 }
308
309 @Override
310 public void setBufferSize(int bufferSize) {
311 if (isCommitted()) {
312 throw new IllegalStateException("Set buffer size after commit");
313 }
314
315
316
317
318 }
319
320 public void setByteBuffer(ByteBuffer byteBuffer) {
321 resetBuffer(true);
322
323 _byteBuffer = byteBuffer;
324
325 if (byteBuffer != null) {
326 _servletOutputStream = new ServletOutputStreamAdapter(
327 new DummyOutputStream());
328
329 calledGetOutputStream = true;
330 }
331 }
332
333 public void setCharBuffer(CharBuffer charBuffer) {
334 resetBuffer(true);
335
336 _charBuffer = charBuffer;
337
338 if (charBuffer != null) {
339 _printWriter = UnsyncPrintWriterPool.borrow(new DummyWriter());
340
341 calledGetWriter = true;
342 }
343 }
344
345 @Override
346 public void setContentLength(int contentLength) {
347
348
349
350
351 }
352
353 public void setString(String string) {
354 setCharBuffer(CharBuffer.wrap(string));
355 }
356
357 @Override
358 protected void resetBuffer(boolean nullOutReferences) {
359 if (nullOutReferences) {
360 calledGetOutputStream = false;
361 calledGetWriter = false;
362
363 _printWriter = null;
364 _servletOutputStream = null;
365 _unsyncByteArrayOutputStream = null;
366 _unsyncStringWriter = null;
367 }
368 else {
369 if (_unsyncByteArrayOutputStream != null) {
370 _unsyncByteArrayOutputStream.reset();
371 }
372
373 if (_unsyncStringWriter != null) {
374 _unsyncStringWriter.reset();
375 }
376
377 if (_byteBuffer != null) {
378 _servletOutputStream = null;
379
380 calledGetOutputStream = false;
381 }
382
383 if (_charBuffer != null) {
384 _printWriter = null;
385
386 calledGetWriter = false;
387 }
388 }
389
390 _byteBuffer = null;
391 _charBuffer = null;
392 }
393
394 private void _flushInternalBuffer() throws IOException {
395 if (calledGetOutputStream) {
396 _servletOutputStream.flush();
397 }
398 else if (calledGetWriter) {
399 _printWriter.flush();
400 }
401 }
402
403 private static ByteBuffer _emptyByteBuffer = ByteBuffer.allocate(0);
404 private static CharBuffer _emptyCharBuffer = CharBuffer.allocate(0);
405
406 private ByteBuffer _byteBuffer;
407 private CharBuffer _charBuffer;
408 private PrintWriter _printWriter;
409 private ServletOutputStream _servletOutputStream;
410 private UnsyncByteArrayOutputStream _unsyncByteArrayOutputStream;
411 private UnsyncStringWriter _unsyncStringWriter;
412
413 }