001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.servlet;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
018    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
024    
025    import java.io.IOException;
026    import java.io.PrintWriter;
027    import java.io.UnsupportedEncodingException;
028    import java.io.Writer;
029    
030    import java.util.Locale;
031    
032    import javax.servlet.ServletOutputStream;
033    import javax.servlet.http.HttpServletResponse;
034    
035    /**
036     * @author Brian Wing Shun Chan
037     * @author Shuyang Zhou
038     * @author Zsolt Balogh
039     */
040    public class StringServletResponse extends HeaderCacheServletResponse {
041    
042            public StringServletResponse(HttpServletResponse response) {
043                    super(response);
044            }
045    
046            @Override
047            public int getBufferSize() {
048                    return _bufferSize;
049            }
050    
051            @Override
052            public ServletOutputStream getOutputStream() {
053                    if (_calledGetWriter) {
054                            throw new IllegalStateException(
055                                    "Cannot obtain OutputStream because Writer is already in use");
056                    }
057    
058                    if (_servletOutputStream == null) {
059                            _unsyncByteArrayOutputStream = new UnsyncByteArrayOutputStream();
060                            _servletOutputStream = new PipingServletOutputStream(
061                                    _unsyncByteArrayOutputStream);
062                    }
063    
064                    _calledGetOutputStream = true;
065    
066                    return _servletOutputStream;
067            }
068    
069            public String getString() {
070                    if (_string != null) {
071                            return _string;
072                    }
073    
074                    if (_calledGetOutputStream) {
075                            try {
076                                    _string = _unsyncByteArrayOutputStream.toString(
077                                            StringPool.UTF8);
078                            }
079                            catch (UnsupportedEncodingException uee) {
080                                    _log.error(uee, uee);
081    
082                                    _string = StringPool.BLANK;
083                            }
084                    }
085                    else if (_calledGetWriter) {
086                            _string = _unsyncStringWriter.toString();
087                    }
088                    else {
089                            _string = StringPool.BLANK;
090                    }
091    
092                    return _string;
093            }
094    
095            public UnsyncByteArrayOutputStream getUnsyncByteArrayOutputStream() {
096                    return _unsyncByteArrayOutputStream;
097            }
098    
099            @Override
100            public PrintWriter getWriter() {
101                    if (_calledGetOutputStream) {
102                            throw new IllegalStateException(
103                                    "Cannot obtain Writer because OutputStream is already in use");
104                    }
105    
106                    if (_printWriter == null) {
107                            _unsyncStringWriter = new UnsyncStringWriter();
108                            _printWriter = UnsyncPrintWriterPool.borrow(_unsyncStringWriter);
109                    }
110    
111                    _calledGetWriter = true;
112    
113                    return _printWriter;
114            }
115    
116            public boolean isCalledGetOutputStream() {
117                    return _calledGetOutputStream;
118            }
119    
120            public boolean isCalledGetWriter() {
121                    return _calledGetWriter;
122            }
123    
124            public void recycle() {
125                    _string = null;
126    
127                    setStatus(SC_OK);
128    
129                    resetBuffer();
130            }
131    
132            @Override
133            public void resetBuffer() {
134                    if (_calledGetOutputStream) {
135                            _calledGetOutputStream = false;
136    
137                            _unsyncByteArrayOutputStream.reset();
138                    }
139                    else if (_calledGetWriter) {
140                            _calledGetWriter = false;
141    
142                            _unsyncStringWriter.reset();
143                    }
144            }
145    
146            @Override
147            public void setBufferSize(int bufferSize) {
148                    _bufferSize = bufferSize;
149            }
150    
151            @Override
152            public void setLocale(Locale locale) {
153            }
154    
155            public void setString(String string) {
156                    _string = string;
157            }
158    
159            public void writeTo(Writer writer) throws IOException {
160                    if (_string != null) {
161                            writer.write(_string);
162                    }
163                    else if (_calledGetWriter) {
164                            StringBundler sb = _unsyncStringWriter.getStringBundler();
165    
166                            sb.writeTo(writer);
167                    }
168                    else {
169                            writer.write(getString());
170                    }
171            }
172    
173            private static Log _log = LogFactoryUtil.getLog(
174                    StringServletResponse.class);
175    
176            private int _bufferSize;
177            private boolean _calledGetOutputStream;
178            private boolean _calledGetWriter;
179            private PrintWriter _printWriter;
180            private ServletOutputStream _servletOutputStream;
181            private String _string;
182            private UnsyncByteArrayOutputStream _unsyncByteArrayOutputStream;
183            private UnsyncStringWriter _unsyncStringWriter;
184    
185    }