001    package railo.runtime.net.http;
002    
003    import java.io.IOException;
004    import java.io.OutputStream;
005    import java.io.PrintWriter;
006    import java.io.Serializable;
007    import java.util.Locale;
008    
009    import javax.servlet.ServletOutputStream;
010    import javax.servlet.http.Cookie;
011    import javax.servlet.http.HttpServletResponse;
012    import javax.servlet.http.HttpServletResponseWrapper;
013    
014    import railo.commons.io.DevNullOutputStream;
015    import railo.commons.lang.Pair;
016    import railo.commons.net.URLEncoder;
017    import railo.runtime.op.Caster;
018    import railo.runtime.type.dt.DateTimeImpl;
019    
020    
021    
022    /**
023     * 
024     */
025    public final class HttpServletResponseWrap extends HttpServletResponseWrapper implements HttpServletResponse,Serializable {
026            
027            private Cookie[] cookies=new Cookie[0];
028            private Pair[] headers=new Pair[0];
029            private int status=200;
030            private String statusCode="OK";
031            private String charset="ISO-8859-1";
032            private int contentLength=-1;
033            private String contentType=null;
034            private Locale locale=Locale.getDefault();
035            private int bufferSize=-1;
036            private boolean commited;
037            //private byte[] outputDatad;
038            private OutputStream out;//=new DevNullOutputStream();
039            private boolean outInit=false;
040            private PrintWriter writer;
041            private ServletOutputStreamDummy outputStream;
042            
043    
044            private static ThreadLocal<Boolean> local=new ThreadLocal<Boolean>();
045    
046    
047            public static void set(boolean value) {
048                    local.set(Caster.toBoolean(value));
049            }
050            public static boolean get() {
051                    return Caster.toBooleanValue(local.get(),false);
052            }
053            public static void release() {
054                    local.set(Boolean.FALSE);
055            }
056    
057            /**
058             * Constructor of the class
059             */
060            public HttpServletResponseWrap(HttpServletResponse rsp) {
061                    this(rsp,DevNullOutputStream.DEV_NULL_OUTPUT_STREAM);
062            }
063    
064            public HttpServletResponseWrap(HttpServletResponse rsp,OutputStream out) {
065                    super(rsp);
066                    this.out=out;
067            }
068            
069            @Override
070            public void addCookie(Cookie cookie) {
071                    Cookie[] tmp = new Cookie[cookies.length+1];
072                    for(int i=0;i<cookies.length;i++) {
073                            tmp[i]=cookies[i];
074                    }
075                    tmp[cookies.length]=cookie;
076                    cookies=tmp;
077            }
078            
079            @Override
080            public boolean containsHeader(String key) {
081                    return ReqRspUtil.get(headers, key)!=null;
082            }
083            
084            @Override
085            public String encodeURL(String value) {
086                    return URLEncoder.encode(value);
087            }
088            @Override
089            public String encodeRedirectURL(String url) {
090                    return URLEncoder.encode(url);
091            }
092            @Override
093            public String encodeUrl(String value) {
094                    return URLEncoder.encode(value);
095            }
096            @Override
097            public String encodeRedirectUrl(String value) {
098                    return URLEncoder.encode(value);
099            }
100            
101            @Override
102            public void sendError(int code, String codeText) throws IOException {
103                    // TODO impl
104            }
105            @Override
106            public void sendError(int code) throws IOException {
107                    // TODO impl
108            }
109            
110            @Override
111            public void sendRedirect(String location) throws IOException {
112                    addHeader("location",location);
113            }
114            @Override
115            public void setDateHeader(String key, long value) {
116                    setHeader(key, new DateTimeImpl(value,false).castToString());
117            }
118            
119            @Override
120            public void addDateHeader(String key, long value) {
121                    addHeader(key, new DateTimeImpl(value,false).castToString());
122            }
123            
124            @Override
125            public void setHeader(String key, String value) {
126                    headers=ReqRspUtil.set(headers, key, value);
127            }
128            
129            @Override
130            public void addHeader(String key, String value) {
131                    headers=ReqRspUtil.add(headers, key, value);
132            }
133            
134            @Override
135            public void setIntHeader(String key, int value) {
136                    setHeader(key, String.valueOf(value));
137            }
138            
139            @Override
140            public void addIntHeader(String key, int value) {
141                    addHeader(key, String.valueOf(value));
142            }
143            @Override
144            public void setStatus(int status) {
145                    this.status=status; 
146            }
147            @Override
148            public void setStatus(int status, String statusCode) {
149                    setStatus(status);
150                    this.statusCode=statusCode;  
151            }
152            
153            @Override
154            public String getCharacterEncoding() {
155                    return charset;
156            }
157            
158            public void setCharacterEncoding(String charset) {
159                    this.charset = charset;
160            }
161            
162            @Override
163            public ServletOutputStream getOutputStream() throws IOException {
164                    //if(writer!=null) throw new IOException("output already initallised as Writer");
165                    if(outputStream!=null) return outputStream;
166                    return outputStream=new ServletOutputStreamDummy(out);
167            }
168            
169            public ServletOutputStream getExistingOutputStream()  {
170                    return outputStream;
171            }
172            
173            @Override
174            public PrintWriter getWriter() throws IOException {
175                    //if(outputStream!=null) throw new IOException("output already initallised as OutputStream");
176                    if(writer!=null) return writer;
177                    return writer= new PrintWriter(getOutputStream());
178                    
179            }
180            
181            public PrintWriter getExistingWriter() {
182                    return writer;
183            }
184            
185            
186            
187            
188            @Override
189            public void setContentLength(int contentLength) {
190                    this.contentLength=contentLength;
191            }
192            @Override
193            public void setContentType(String contentType) {
194                    this.contentType=contentType;
195            }
196            @Override
197            public void setBufferSize(int size) {
198                    this.bufferSize=size;
199            }
200            @Override
201            public int getBufferSize() {
202                    return bufferSize;
203            }
204            @Override
205            public void flushBuffer() throws IOException {
206                    if(writer!=null)writer.flush();
207                    else if(outputStream!=null)outputStream.flush();
208                    commited = true;
209            }
210            @Override
211            public void resetBuffer() {
212                    commited = true;
213            }
214            @Override
215            public boolean isCommitted() {
216                    return commited;
217            }
218            @Override
219            public void reset() {
220                    commited = true;
221            }
222            @Override
223            public void setLocale(Locale locale) {
224                    this.locale=locale;
225            }
226            @Override
227            public Locale getLocale() {
228                    return locale;
229            }
230    
231            /**
232             * @return the charset
233             */
234            public String getCharsetEncoding() {
235                    return charset;
236            }
237    
238            /**
239             * @return the commited
240             */
241            public boolean isCommited() {
242                    return commited;
243            }
244    
245            /**
246             * @return the contentLength
247             */
248            public int getContentLength() {
249                    return contentLength;
250            }
251    
252            /**
253             * @return the contentType
254             */
255            public String getContentType() {
256                    return contentType;
257            }
258    
259            /**
260             * @return the cookies
261             */
262            public Cookie[] getCookies() {
263                    return cookies;
264            }
265    
266            /**
267             * @return the headers
268             */
269            public Pair[] getHeaders() {
270                    return headers;
271            }
272    
273            /* *
274             * @return the outputData
275             * /
276            public byte[] getOutputData() {
277                    return outputData;
278            }
279    
280            public void setOutputData(byte[] outputData) {
281                    this.outputData=outputData;
282            }*/
283    
284            /**
285             * @return the status
286             */
287            public int getStatus() {
288                    return status;
289            }
290    
291            /**
292             * @return the statusCode
293             */
294            public String getStatusCode() {
295                    return statusCode;
296            }
297    
298            
299            
300    }