1 48 49 50 package com.caucho.portal.generic.context; 51 52 import com.caucho.portal.generic.BufferFactory; 53 import com.caucho.portal.generic.PortletByteBuffer; 54 import com.caucho.portal.generic.PortletCharBuffer; 55 56 import java.io.IOException ; 57 import java.io.OutputStream ; 58 import java.io.PrintWriter ; 59 import java.util.ArrayList ; 60 import java.util.Iterator ; 61 import java.util.LinkedHashMap ; 62 import java.util.Map ; 63 import java.util.logging.Logger ; 64 65 public class BufferedResponseHandler extends AbstractResponseHandler 66 { 67 protected static final Logger log = 68 Logger.getLogger(BufferedResponseHandler.class.getName()); 69 70 private static final int NOT_ALLOCATED = Integer.MIN_VALUE; 71 72 private BufferFactory _bufferFactory; 73 74 private int _initialBufferSize = -1; 76 77 78 private LinkedHashMap <String , Object > _propertiesMap; 79 80 private int _bufferSize = NOT_ALLOCATED; private PortletCharBuffer _charBuffer; 82 private PortletByteBuffer _byteBuffer; 83 private PrintWriter _writer; 84 private OutputStream _outputStream; 85 private boolean _isCommitted; 86 87 public BufferedResponseHandler( ResponseHandler responseHandler, 88 BufferFactory bufferFactory, 89 int initialBufferSize) 90 { 91 open(responseHandler, bufferFactory, initialBufferSize ); 92 } 93 94 public void open( ResponseHandler responseHandler, 95 BufferFactory bufferFactory, 96 int initialBufferSize ) 97 { 98 super.open(responseHandler); 99 _bufferFactory = bufferFactory; 100 _initialBufferSize = initialBufferSize; 101 } 102 103 public void finish() 104 throws IOException 105 { 106 if (!isError()) 107 flushBuffer(); 108 109 freeBuffers(true); 110 111 if (_propertiesMap != null) 112 _propertiesMap.clear(); 113 114 _isCommitted = false; 115 _writer = null; 116 _outputStream = null; 117 _bufferSize = NOT_ALLOCATED; 118 _initialBufferSize = -1; 119 _bufferFactory = null; 120 121 super.finish(); 122 } 123 124 public void setBufferSize(int bufferSize) 125 { 126 if (_bufferSize != NOT_ALLOCATED) { 127 if (bufferSize > _bufferSize) { 128 if (!_isCommitted) { 129 freeBuffers(true); 130 _initialBufferSize = bufferSize; 131 } 132 else { 133 if (_bufferSize == 0 && _initialBufferSize != 0) 134 throw new IllegalStateException ( 135 "buffer already committed to `" + _bufferSize + "'"); 136 else 137 throw new IllegalStateException ("buffer already committed"); 138 } 139 } 140 } 141 else 142 _initialBufferSize = bufferSize; 143 } 144 145 public int getBufferSize() 146 { 147 if (_bufferSize != NOT_ALLOCATED) 148 return _bufferSize; 149 else if (_initialBufferSize != -1) 150 return _initialBufferSize; 151 else 152 return _bufferFactory.getDefaultBufferSize(); 153 } 154 155 public void setProperty(String name, String value) 156 { 157 if (_isCommitted) 158 throw new IllegalStateException ("response committed"); 159 160 if (_propertiesMap == null) 161 _propertiesMap = new LinkedHashMap <String , Object >(); 162 163 _propertiesMap.put(name, value); 164 } 165 166 public void addProperty(String name, String value) 167 { 168 if (_isCommitted) 169 throw new IllegalStateException ("response committed"); 170 171 Object existingValue = null; 172 173 if (_propertiesMap == null) 174 _propertiesMap = new LinkedHashMap <String , Object >(); 175 else 176 existingValue = _propertiesMap.get(name); 177 178 if (existingValue == null) { 179 _propertiesMap.put(name, value); 180 } 181 else if (existingValue instanceof ArrayList ) { 182 ((ArrayList <String >) existingValue).add(value); 183 } 184 else { 185 ArrayList <String > valueList = new ArrayList <String >(); 186 valueList.add((String ) existingValue); 187 valueList.add(value); 188 } 189 } 190 191 public boolean isCommitted() 192 { 193 return _isCommitted; 194 } 195 196 private void allocateCharBufferIfNeeded() 197 { 198 if (_byteBuffer != null) 199 throw new IllegalStateException ( 200 "cannot allocate char buffer, byte buffer already allocated"); 201 202 if (_bufferSize == NOT_ALLOCATED) { 203 if (_initialBufferSize != 0) { 204 _charBuffer = _bufferFactory.allocateCharBuffer(_initialBufferSize); 205 _bufferSize = _charBuffer.getCapacity(); 206 } 207 else 208 _bufferSize = 0; 209 } 210 } 211 212 private void allocateByteBufferIfNeeded() 213 { 214 if (_charBuffer != null) 215 throw new IllegalStateException ( 216 "cannot allocate byte buffer, char buffer already allocated"); 217 218 if (_bufferSize == NOT_ALLOCATED) { 219 if (_initialBufferSize != 0) { 220 _byteBuffer = _bufferFactory.allocateByteBuffer(_initialBufferSize); 221 _bufferSize = _byteBuffer.getCapacity(); 222 } 223 else 224 _bufferSize = 0; 225 } 226 } 227 228 public PrintWriter getWriter() 229 throws IOException 230 { 231 checkErrorOrFail(); 232 233 if (_writer != null) 234 return _writer; 235 236 return _writer = super.getWriter(); 237 } 238 239 public OutputStream getOutputStream() 240 throws IOException 241 { 242 checkErrorOrFail(); 243 244 if (_outputStream != null) 245 return _outputStream; 246 247 return _outputStream = super.getOutputStream(); 248 } 249 250 public void reset() 251 { 252 resetBuffer(); 253 254 if (_propertiesMap != null) 255 _propertiesMap.clear(); 256 } 257 258 public void resetBuffer() 259 { 260 if (_isCommitted) 261 throw new IllegalStateException ("response is already committed"); 262 263 if (_byteBuffer != null) 264 _byteBuffer.reset(); 265 266 if (_charBuffer != null) 267 _charBuffer.reset(); 268 269 freeBuffers(true); 270 } 271 272 275 private void freeBuffers(boolean isAllocateAgain) 276 { 277 PortletCharBuffer charBuffer = _charBuffer; 278 PortletByteBuffer byteBuffer = _byteBuffer; 279 280 _charBuffer = null; 281 _byteBuffer = null; 282 283 if (charBuffer != null) { 284 if (charBuffer.size() != 0) 285 throw new IllegalStateException ("still content in buffer"); 286 287 charBuffer.finish(); 288 } 289 290 if (byteBuffer != null) { 291 if (byteBuffer.size() != 0) 292 throw new IllegalStateException ("still content in buffer"); 293 294 byteBuffer.finish(); 295 } 296 297 if (isAllocateAgain) 298 _bufferSize = NOT_ALLOCATED; 299 } 300 301 public void flushBuffer() 302 throws IOException 303 { 304 checkErrorOrFail(); 305 306 try { 307 flushProperties(); 308 flushBufferOnly(); 309 } 310 catch (Exception ex) { 311 setError(ex); 312 } 313 } 314 315 private void flushProperties() 316 { 317 if (_propertiesMap != null && _propertiesMap.size() > 0) { 318 319 _isCommitted = true; 320 321 Iterator <Map.Entry <String , Object >> iter 322 = _propertiesMap.entrySet().iterator(); 323 324 do { 325 Map.Entry <String , Object > entry = iter.next(); 326 String name = entry.getKey(); 327 Object value = entry.getValue(); 328 329 if (value instanceof ArrayList ) { 330 ArrayList <String > valueList = (ArrayList <String >) value; 331 332 for (int i = 0; i < valueList.size(); i++) { 333 super.addProperty(name, valueList.get(i)); 334 } 335 } 336 else { 337 super.setProperty(name, (String ) value); 338 } 339 340 iter.remove(); 341 } while (iter.hasNext()); 342 } 343 } 344 345 private void flushBufferOnly() 346 throws IOException 347 { 348 if (_charBuffer != null && _charBuffer.size() > 0) { 349 _isCommitted = true; 350 _charBuffer.flush(super.getUnderlyingWriter()); 351 } 352 353 if (_byteBuffer != null && _byteBuffer.size() > 0) { 354 _isCommitted = true; 355 _byteBuffer.flush(super.getUnderlyingOutputStream()); 356 } 357 358 360 freeBuffers(false); 361 } 362 363 protected void print(char buf[], int off, int len) 364 throws IOException 365 { 366 if (len == 0) 367 return; 368 369 allocateCharBufferIfNeeded(); 370 371 checkErrorOrFail(); 372 373 if (_charBuffer == null) { 374 _isCommitted = true; 375 super.print(buf, off, len); 376 } 377 else { 378 if (!_charBuffer.print(buf, off, len)) { 379 flushBuffer(); 380 _isCommitted = true; 381 super.print(buf, off, len); 382 } 383 } 384 } 385 386 protected void print(String str, int off, int len) 387 throws IOException 388 { 389 if (len == 0) 390 return; 391 392 allocateCharBufferIfNeeded(); 393 394 checkErrorOrFail(); 395 396 if (_charBuffer == null) { 397 _isCommitted = true; 398 super.print(str, off, len); 399 } 400 else { 401 if (!_charBuffer.print(str, off, len)) { 402 flushBuffer(); 403 _isCommitted = true; 404 super.print(str, off, len); 405 } 406 } 407 } 408 409 protected void print(char c) 410 throws IOException 411 { 412 allocateCharBufferIfNeeded(); 413 414 checkErrorOrFail(); 415 416 if (_charBuffer == null) { 417 _isCommitted = true; 418 super.print(c); 419 } 420 else { 421 if (!_charBuffer.print(c)) { 422 flushBuffer(); 423 _isCommitted = true; 424 super.print(c); 425 } 426 } 427 } 428 429 protected void write(byte[] buf, int off, int len) 430 throws IOException 431 { 432 if (len == 0) 433 return; 434 435 allocateByteBufferIfNeeded(); 436 437 checkErrorOrFail(); 438 439 if (_byteBuffer == null) { 440 _isCommitted = true; 441 super.write(buf, off, len); 442 } 443 else { 444 if (!_byteBuffer.write(buf, off, len)) { 445 flushBuffer(); 446 _isCommitted = true; 447 super.write(buf, off, len); 448 } 449 } 450 } 451 452 protected void write(byte b) 453 throws IOException 454 { 455 checkErrorOrFail(); 456 457 allocateByteBufferIfNeeded(); 458 459 if (_byteBuffer == null) { 460 _isCommitted = true; 461 super.write(b); 462 } 463 else { 464 if (!_byteBuffer.write(b)) { 465 flushBuffer(); 466 _isCommitted = true; 467 super.write(b); 468 } 469 } 470 } 471 } 472 | Popular Tags |