001
014
015 package com.liferay.portal.kernel.servlet;
016
017 import com.liferay.portal.kernel.io.RestrictedByteArrayCacheOutputStream;
018 import com.liferay.portal.kernel.io.RestrictedByteArrayCacheOutputStream.FlushPreAction;
019 import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
020
021 import java.io.IOException;
022 import java.io.PrintWriter;
023
024 import java.nio.ByteBuffer;
025
026 import javax.servlet.ServletOutputStream;
027 import javax.servlet.ServletResponse;
028 import javax.servlet.http.HttpServletResponse;
029
030
033 public class RestrictedByteBufferCacheServletResponse
034 extends MetaInfoCacheServletResponse {
035
036 public RestrictedByteBufferCacheServletResponse(
037 HttpServletResponse response, int cacheCapacity) {
038
039 super(response);
040
041 _cacheCapacity = cacheCapacity;
042 }
043
044 public void flushCache() throws IOException {
045 if (_restrictedByteArrayCacheOutputStream != null) {
046 _restrictedByteArrayCacheOutputStream.flush();
047 }
048 }
049
050 @Override
051 public int getBufferSize() {
052 if (_restrictedByteArrayCacheOutputStream == null) {
053 return _cacheCapacity;
054 }
055
056 if (_restrictedByteArrayCacheOutputStream.isOverflowed()) {
057 return 0;
058 }
059
060 return _restrictedByteArrayCacheOutputStream.getCacheCapacity();
061 }
062
063 public ByteBuffer getByteBuffer() {
064 if (_restrictedByteArrayCacheOutputStream == null) {
065 return _emptyByteBuffer;
066 }
067
068 return _restrictedByteArrayCacheOutputStream.unsafeGetByteBuffer();
069 }
070
071 @Override
072 public ServletOutputStream getOutputStream() throws IOException {
073 if (calledGetWriter) {
074 throw new IllegalStateException(
075 "Unable to obtain OutputStream because Writer is already in " +
076 "use");
077 }
078
079 if (_servletOutputStream != null) {
080 return _servletOutputStream;
081 }
082
083 _restrictedByteArrayCacheOutputStream =
084 new RestrictedByteArrayCacheOutputStream(
085 super.getOutputStream(), _cacheCapacity,
086 new FinishResponseFlushPreAction());
087
088 _servletOutputStream = new ServletOutputStreamAdapter(
089 _restrictedByteArrayCacheOutputStream);
090
091 calledGetOutputStream = true;
092
093 return _servletOutputStream;
094 }
095
096 @Override
097 public PrintWriter getWriter() throws IOException {
098 if (calledGetOutputStream) {
099 throw new IllegalStateException(
100 "Unable to obtain Writer because OutputStream is already in " +
101 "use");
102 }
103
104 if (_printWriter != null) {
105 return _printWriter;
106 }
107
108 ServletResponse servletResponse = getResponse();
109
110 _restrictedByteArrayCacheOutputStream =
111 new RestrictedByteArrayCacheOutputStream(
112 servletResponse.getOutputStream(), _cacheCapacity,
113 new FinishResponseFlushPreAction());
114
115 _printWriter = UnsyncPrintWriterPool.borrow(
116 _restrictedByteArrayCacheOutputStream, getCharacterEncoding());
117
118 calledGetWriter = true;
119
120 return _printWriter;
121 }
122
123 public boolean isOverflowed() {
124 if (_restrictedByteArrayCacheOutputStream == null) {
125 return false;
126 }
127
128 return _restrictedByteArrayCacheOutputStream.isOverflowed();
129 }
130
131 @Override
132 public void setBufferSize(int bufferSize) {
133 if (isCommitted()) {
134 throw new IllegalStateException("Set buffer size after commit");
135 }
136
137
138
139
140 }
141
142 @Override
143 protected void resetBuffer(boolean nullOutReferences) {
144 if (nullOutReferences) {
145 calledGetOutputStream = false;
146 calledGetWriter = false;
147
148 _printWriter = null;
149 _servletOutputStream = null;
150 _restrictedByteArrayCacheOutputStream = null;
151 }
152 else if (_restrictedByteArrayCacheOutputStream != null) {
153 _restrictedByteArrayCacheOutputStream.reset();
154 }
155 }
156
157 private static ByteBuffer _emptyByteBuffer = ByteBuffer.allocate(0);
158
159 private int _cacheCapacity;
160 private PrintWriter _printWriter;
161 private RestrictedByteArrayCacheOutputStream
162 _restrictedByteArrayCacheOutputStream;
163 private ServletOutputStream _servletOutputStream;
164
165 private class FinishResponseFlushPreAction implements FlushPreAction {
166
167 @Override
168 public void beforeFlush() throws IOException {
169 finishResponse(false);
170 }
171 }
172
173 }