001 package railo.runtime.writer; 002 003 import java.io.IOException; 004 import java.io.OutputStream; 005 import java.io.Writer; 006 007 import javax.servlet.ServletOutputStream; 008 import javax.servlet.http.HttpServletResponse; 009 010 import railo.commons.io.IOUtil; 011 import railo.commons.lang.ByteBuffer; 012 import railo.runtime.net.http.ReqRspUtil; 013 014 /** 015 * Implementation of a JSpWriter 016 */ 017 public class JspWriterImplByteBuffer extends CFMLWriter { 018 019 private static final int BUFFER_SIZE = 1024; 020 021 private ServletOutputStream out; 022 023 private HttpServletResponse response; 024 025 private boolean flushed; 026 027 private String headData; 028 029 private ByteBuffer buffer; 030 031 private boolean closed=false; 032 033 private String charset; 034 035 /** 036 * constructor of the class 037 * @param response Response Object 038 * @param bufferSize buffer Size 039 * @param autoFlush do auto flush Content 040 */ 041 public JspWriterImplByteBuffer(HttpServletResponse response, int bufferSize, boolean autoFlush) { 042 super(bufferSize, autoFlush); 043 this.response=response; 044 this.autoFlush=autoFlush; 045 this.bufferSize=bufferSize; 046 charset = response.getCharacterEncoding(); 047 buffer=new ByteBuffer(charset,BUFFER_SIZE); 048 //initBuffer(response.getCharacterEncoding()); 049 } 050 051 /** 052 * constructor of the class 053 * @param response Response Object 054 */ 055 public JspWriterImplByteBuffer(HttpServletResponse response) { 056 this(response, BUFFER_SIZE, false); 057 } 058 059 private void _check() throws IOException { 060 if(autoFlush && buffer.size()>bufferSize) { 061 _flush(); 062 } 063 } 064 065 /** 066 * @throws IOException 067 */ 068 protected void initOut() throws IOException { 069 if (out == null) { 070 out=response.getOutputStream(); 071 } 072 } 073 074 /*public void splitForCacheTo(Resource res) throws IOException { 075 initOut(); 076 out=new CacheWriter(out,res); 077 } 078 079 public void clearCacheSplit() { 080 if(out instanceof CacheWriter) { 081 CacheWriter cw = (CacheWriter)out; 082 out=cw.getOut(); 083 if(cw.getCacheFile().exists())cw.getCacheFile().delete(); 084 } 085 } */ 086 087 088 /** 089 * @see javax.servlet.jsp.JspWriter#print(char[]) 090 */ 091 public void print(char[] arg) throws IOException { 092 buffer.append(arg); 093 _check(); 094 } 095 096 /** 097 * reset configuration of buffer 098 * @param bufferSize size of the buffer 099 * @param autoFlush does the buffer autoflush 100 * @throws IOException 101 */ 102 public void setBufferConfig(int bufferSize, boolean autoFlush) throws IOException { 103 this.bufferSize=bufferSize; 104 this.autoFlush=autoFlush; 105 _check(); 106 } 107 108 /** 109 * 110 * @param headData 111 * @throws IOException 112 */ 113 public void appendHTMLHead(String headData) throws IOException { 114 if(!flushed) { 115 if(this.headData==null)this.headData=headData; 116 else this.headData+=headData; 117 } 118 else throw new IOException("page already flushed"); 119 } 120 121 /** 122 * @see railo.runtime.writer.CFMLWriter#writeHTMLHead(java.lang.String) 123 */ 124 public void writeHTMLHead(String headData) throws IOException { 125 if(!flushed) { 126 this.headData=headData; 127 } 128 else throw new IOException("page already flushed"); 129 } 130 131 132 133 /** 134 * @see railo.runtime.writer.CFMLWriter#getHTMLHead() 135 */ 136 public String getHTMLHead() throws IOException { 137 if(flushed) throw new IOException("page already flushed"); 138 return headData==null?"":headData; 139 } 140 141 /** 142 * @see railo.runtime.writer.CFMLWriter#resetHTMLHead() 143 */ 144 public void resetHTMLHead() throws IOException { 145 if(flushed) throw new IOException("page already flushed"); 146 headData=null; 147 } 148 149 /** 150 * just a wrapper function for ACF 151 * @throws IOException 152 */ 153 public void initHeaderBuffer() throws IOException{ 154 resetHTMLHead(); 155 } 156 157 /** 158 * @see java.io.Writer#write(char[], int, int) 159 */ 160 public void write(char[] cbuf, int off, int len) throws IOException { 161 buffer.append(cbuf,off,len); 162 _check(); 163 } 164 165 /** 166 * @see javax.servlet.jsp.JspWriter#clear() 167 */ 168 public void clear() throws IOException { 169 if (flushed) throw new IOException("jsp writer is already flushed"); 170 clearBuffer(); 171 } 172 173 /** 174 * @see javax.servlet.jsp.JspWriter#clearBuffer() 175 */ 176 public void clearBuffer() { 177 buffer=new ByteBuffer(charset,BUFFER_SIZE); 178 } 179 180 /** 181 * @see java.io.Writer#flush() 182 */ 183 public void flush() throws IOException { 184 flushBuffer(); 185 // weil flushbuffer das out erstellt muss ich nicht mehr checken 186 out.flush(); 187 } 188 /** 189 * @see java.io.Writer#flush() 190 */ 191 private void _flush() throws IOException { 192 flushBuffer(); 193 // weil flushbuffer das out erstellt muss ich nicht mehr checken 194 out.flush(); 195 } 196 197 /** 198 * Flush the output buffer to the underlying character stream, without 199 * flushing the stream itself. This method is non-private only so that it 200 * may be invoked by PrintStream. 201 * @throws IOException 202 */ 203 protected final void flushBuffer() throws IOException { 204 flushed = true; 205 initOut(); 206 _writeOut(out,false); 207 clearBuffer(); 208 } 209 210 private void _writeOut(OutputStream os,boolean writeLength) throws IOException { 211 if(headData==null) { 212 if(writeLength)ReqRspUtil.setContentLength(response,buffer.size()); 213 buffer.writeOut(os); 214 return; 215 //return buffer.toString(); 216 } 217 if(writeLength)ReqRspUtil.setContentLength(response,buffer.size()+headData.getBytes(charset).length); 218 219 String str=buffer.toString(); 220 Writer writer = IOUtil.getWriter(os, charset); 221 int index=str.indexOf("</head>"); 222 if(index==-1) { 223 str= headData.concat(str); 224 headData=null; 225 226 writer.write(str); 227 writer.flush(); 228 return; 229 //return str; 230 } 231 str= str.substring(0,index).concat(headData).concat(str.substring(index)); 232 headData=null; 233 writer.write(str); 234 writer.flush(); 235 //return str; 236 } 237 238 239 240 /** 241 * @see java.io.Writer#close() 242 */ 243 public void close() throws IOException { 244 if (response == null || closed) return; 245 if(out==null) { 246 //response.setContentLength(buffer.size()); 247 initOut(); 248 _writeOut(out,!flushed); 249 250 251 //byte[] barr = _toString().getBytes(response.getCharacterEncoding()); 252 //response.setContentLength(barr.length); 253 //ServletOutputStream os = response.getOutputStream(); 254 //os.write(barr); 255 out.flush(); 256 out.close(); 257 } 258 else { 259 flush(); 260 out.close(); 261 out = null; 262 } 263 closed = true; 264 } 265 266 /** 267 * @see javax.servlet.jsp.JspWriter#getRemaining() 268 */ 269 public int getRemaining() { 270 return bufferSize - buffer.size(); 271 } 272 273 /** 274 * @see javax.servlet.jsp.JspWriter#newLine() 275 */ 276 public void newLine() throws IOException { 277 println(); 278 } 279 280 /** 281 * @see javax.servlet.jsp.JspWriter#print(boolean) 282 */ 283 public void print(boolean arg) throws IOException { 284 print(arg?new char[]{'t','r','u','e'}:new char[]{'f','a','l','s','e'}); 285 } 286 287 /** 288 * @see javax.servlet.jsp.JspWriter#print(char) 289 */ 290 public void print(char arg) throws IOException { 291 buffer.append(arg); 292 _check(); 293 } 294 295 /** 296 * @see javax.servlet.jsp.JspWriter#print(int) 297 */ 298 public void print(int arg) throws IOException { 299 _print(String.valueOf(arg)); 300 } 301 302 /** 303 * @see javax.servlet.jsp.JspWriter#print(long) 304 */ 305 public void print(long arg) throws IOException { 306 _print(String.valueOf(arg)); 307 308 } 309 310 /** 311 * @see javax.servlet.jsp.JspWriter#print(float) 312 */ 313 public void print(float arg) throws IOException { 314 _print(String.valueOf(arg)); 315 } 316 317 /** 318 * @see javax.servlet.jsp.JspWriter#print(double) 319 */ 320 public void print(double arg) throws IOException { 321 _print(String.valueOf(arg)); 322 } 323 324 /** 325 * @see javax.servlet.jsp.JspWriter#print(java.lang.String) 326 */ 327 public void print(String arg) throws IOException { 328 buffer.append(arg); 329 _check(); 330 } 331 332 /** 333 * @see javax.servlet.jsp.JspWriter#print(java.lang.Object) 334 */ 335 public void print(Object arg) throws IOException { 336 _print(String.valueOf(arg)); 337 } 338 339 /** 340 * @see javax.servlet.jsp.JspWriter#println() 341 */ 342 public void println() throws IOException { 343 _print("\n"); 344 345 } 346 347 /** 348 * @see javax.servlet.jsp.JspWriter#println(boolean) 349 */ 350 public void println(boolean arg) throws IOException { 351 print(arg?new char[]{'t','r','u','e','\n'}:new char[]{'f','a','l','s','e','\n'}); 352 } 353 354 /** 355 * @see javax.servlet.jsp.JspWriter#println(char) 356 */ 357 public void println(char arg) throws IOException { 358 print(new char[]{arg,'\n'}); 359 } 360 361 /** 362 * @see javax.servlet.jsp.JspWriter#println(int) 363 */ 364 public void println(int arg) throws IOException { 365 print(arg); 366 println(); 367 } 368 369 /** 370 * @see javax.servlet.jsp.JspWriter#println(long) 371 */ 372 public void println(long arg) throws IOException { 373 print(arg); 374 println(); 375 } 376 377 /** 378 * @see javax.servlet.jsp.JspWriter#println(float) 379 */ 380 public void println(float arg) throws IOException { 381 print(arg); 382 println(); 383 } 384 385 /** 386 * @see javax.servlet.jsp.JspWriter#println(double) 387 */ 388 public void println(double arg) throws IOException { 389 print(arg); 390 println(); 391 } 392 393 /** 394 * @see javax.servlet.jsp.JspWriter#println(char[]) 395 */ 396 public void println(char[] arg) throws IOException { 397 print(arg); 398 println(); 399 } 400 401 /** 402 * @see javax.servlet.jsp.JspWriter#println(java.lang.String) 403 */ 404 public void println(String arg) throws IOException { 405 _print(arg); 406 println(); 407 } 408 409 /** 410 * @see javax.servlet.jsp.JspWriter#println(java.lang.Object) 411 */ 412 public void println(Object arg) throws IOException { 413 print(arg); 414 println(); 415 } 416 417 /** 418 * @see java.io.Writer#write(char[]) 419 */ 420 public void write(char[] cbuf) throws IOException { 421 print(cbuf); 422 } 423 424 /** 425 * @see java.io.Writer#write(int) 426 */ 427 public void write(int c) throws IOException { 428 print(c); 429 } 430 431 /** 432 * @see java.io.Writer#write(java.lang.String, int, int) 433 */ 434 public void write(String str, int off, int len) throws IOException { 435 write(str.toCharArray(),off,len); 436 } 437 438 /** 439 * @see java.io.Writer#write(java.lang.String) 440 */ 441 public void write(String str) throws IOException { 442 _print(str); 443 } 444 445 /** 446 * @return Returns the flushed. 447 */ 448 public boolean isFlushed() { 449 return flushed; 450 } 451 452 public void setClosed(boolean closed) { 453 this.closed=closed; 454 } 455 456 private void _print(String arg) throws IOException { 457 buffer.append(arg); 458 _check(); 459 } 460 461 /** 462 * @see railo.runtime.writer.CFMLWriter#getResponseStream() 463 */ 464 public OutputStream getResponseStream() throws IOException { 465 initOut(); 466 return out; 467 } 468 469 /** 470 * @see railo.runtime.writer.CFMLWriter#writeRaw(java.lang.String) 471 */ 472 public void writeRaw(String str) throws IOException { 473 write(str); 474 } 475 476 }