001: package org.apache.roller.util.cache;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.IOException;
005: import java.io.OutputStreamWriter;
006: import java.io.PrintWriter;
007: import java.io.Serializable;
008: import java.io.UnsupportedEncodingException;
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: /**
013: * A utility class for storing cached content written to a java.io.Writer.
014: */
015: public class CachedContent implements Serializable {
016:
017: private static Log log = LogFactory.getLog(CachedContent.class);
018:
019: // default to an 8K buffered cache
020: public static final int DEFAULT_SIZE = 8192;
021:
022: // the byte array we use to maintain the cached content
023: private byte[] content = new byte[0];
024:
025: // content-type of data in byte array
026: private String contentType = null;
027:
028: // Use a byte array output stream to cached the output bytes
029: private transient ByteArrayOutputStream outstream = null;
030:
031: // The PrintWriter that users will be writing to
032: private transient PrintWriter cachedWriter = null;
033:
034: public CachedContent(int size) {
035:
036: // construct output stream
037: if (size > 0) {
038: this .outstream = new ByteArrayOutputStream(size);
039: } else {
040: this .outstream = new ByteArrayOutputStream(DEFAULT_SIZE);
041: }
042:
043: // construct writer from output stream
044: try {
045: this .cachedWriter = new PrintWriter(new OutputStreamWriter(
046: this .outstream, "UTF-8"));
047: } catch (UnsupportedEncodingException e) {
048: // shouldn't be possible, java always supports utf-8
049: throw new RuntimeException("Encoding problem", e);
050: }
051: }
052:
053: public CachedContent(int size, String contentType) {
054: this (size);
055: this .contentType = contentType;
056: }
057:
058: /**
059: * Get the content cached in this object as a byte array. If you convert
060: * this back to a string yourself, be sure to re-encode in "UTF-8".
061: *
062: * NOTE: the content is only a representation of the data written to the
063: * enclosed Writer up until the last call to flush().
064: */
065: public byte[] getContent() {
066: return this .content;
067: }
068:
069: /**
070: * Get the content cached in this object as a String.
071: *
072: * NOTE: the content is only a representation of the data written to the
073: * enclosed Writer up until the last call to flush().
074: */
075: public String getContentAsString() {
076: try {
077: return new String(this .content, "UTF-8");
078: } catch (UnsupportedEncodingException uex) {
079: // shouldn't ever happen - violates Java Spec.
080: throw new RuntimeException(uex);
081: }
082: }
083:
084: public PrintWriter getCachedWriter() {
085: return cachedWriter;
086: }
087:
088: public String getContentType() {
089: return contentType;
090: }
091:
092: /**
093: * Called to flush any output in the cached Writer to
094: * the cached content for more permanent storage.
095: *
096: * @throws IllegalStateException if calling flush() after a close()
097: */
098: public void flush() {
099:
100: if (this .outstream == null) {
101: throw new IllegalStateException(
102: "Cannot flush() after a close()!");
103: }
104:
105: this .cachedWriter.flush();
106: this .content = this .outstream.toByteArray();
107:
108: log.debug("FLUSHED " + this .content.length);
109: }
110:
111: /**
112: * Close this CachedContent from further writing.
113: */
114: public void close() throws IOException {
115:
116: if (this .cachedWriter != null) {
117: this .cachedWriter.flush();
118: this .cachedWriter.close();
119: this .cachedWriter = null;
120: }
121:
122: if (this .outstream != null) {
123: this .content = this .outstream.toByteArray();
124: this .outstream.close();
125: this .outstream = null;
126: }
127:
128: log.debug("CLOSED");
129: }
130:
131: }
|