KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > context > BufferedResponseHandler


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Sam
47  */

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 JavaDoc;
57 import java.io.OutputStream JavaDoc;
58 import java.io.PrintWriter JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.LinkedHashMap JavaDoc;
62 import java.util.Map JavaDoc;
63 import java.util.logging.Logger JavaDoc;
64
65 public class BufferedResponseHandler extends AbstractResponseHandler
66 {
67   protected static final Logger JavaDoc 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   // size of buffer to allocate when Writer or OutputStream is obtained
75
private int _initialBufferSize = -1;
76
77
78   private LinkedHashMap JavaDoc<String JavaDoc, Object JavaDoc> _propertiesMap;
79
80   private int _bufferSize = NOT_ALLOCATED; // size allocated
81
private PortletCharBuffer _charBuffer;
82   private PortletByteBuffer _byteBuffer;
83   private PrintWriter JavaDoc _writer;
84   private OutputStream JavaDoc _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 JavaDoc
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 JavaDoc(
135                 "buffer already committed to `" + _bufferSize + "'");
136           else
137             throw new IllegalStateException JavaDoc("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 JavaDoc name, String JavaDoc value)
156   {
157     if (_isCommitted)
158       throw new IllegalStateException JavaDoc("response committed");
159
160     if (_propertiesMap == null)
161       _propertiesMap = new LinkedHashMap JavaDoc<String JavaDoc, Object JavaDoc>();
162
163     _propertiesMap.put(name, value);
164   }
165
166   public void addProperty(String JavaDoc name, String JavaDoc value)
167   {
168     if (_isCommitted)
169       throw new IllegalStateException JavaDoc("response committed");
170
171     Object JavaDoc existingValue = null;
172
173     if (_propertiesMap == null)
174       _propertiesMap = new LinkedHashMap JavaDoc<String JavaDoc, Object JavaDoc>();
175     else
176       existingValue = _propertiesMap.get(name);
177
178     if (existingValue == null) {
179       _propertiesMap.put(name, value);
180     }
181     else if (existingValue instanceof ArrayList JavaDoc) {
182       ((ArrayList JavaDoc<String JavaDoc>) existingValue).add(value);
183     }
184     else {
185       ArrayList JavaDoc<String JavaDoc> valueList = new ArrayList JavaDoc<String JavaDoc>();
186       valueList.add((String JavaDoc) 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 JavaDoc(
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 JavaDoc(
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 JavaDoc getWriter()
229     throws IOException JavaDoc
230   {
231     checkErrorOrFail();
232
233     if (_writer != null)
234       return _writer;
235
236     return _writer = super.getWriter();
237   }
238
239   public OutputStream JavaDoc getOutputStream()
240     throws IOException JavaDoc
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 JavaDoc("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   /**
273    * @param isAllocateAgain allow them to be allocated again on next write
274    */

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 JavaDoc("still content in buffer");
286
287       charBuffer.finish();
288     }
289
290     if (byteBuffer != null) {
291       if (byteBuffer.size() != 0)
292         throw new IllegalStateException JavaDoc("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 JavaDoc
303   {
304     checkErrorOrFail();
305
306     try {
307       flushProperties();
308       flushBufferOnly();
309     }
310     catch (Exception JavaDoc 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 JavaDoc<Map.Entry JavaDoc<String JavaDoc, Object JavaDoc>> iter
322         = _propertiesMap.entrySet().iterator();
323
324       do {
325         Map.Entry JavaDoc<String JavaDoc, Object JavaDoc> entry = iter.next();
326         String JavaDoc name = entry.getKey();
327         Object JavaDoc value = entry.getValue();
328
329         if (value instanceof ArrayList JavaDoc) {
330           ArrayList JavaDoc<String JavaDoc> valueList = (ArrayList JavaDoc<String JavaDoc>) 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 JavaDoc) value);
338         }
339
340         iter.remove();
341       } while (iter.hasNext());
342     }
343   }
344
345   private void flushBufferOnly()
346     throws IOException JavaDoc
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     // after they are flushed once, don't need them anymore
359

360     freeBuffers(false);
361   }
362
363   protected void print(char buf[], int off, int len)
364     throws IOException JavaDoc
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 JavaDoc str, int off, int len)
387     throws IOException JavaDoc
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 JavaDoc
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 JavaDoc
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 JavaDoc
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