001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.bean.helpers;
018:
019: import java.io.ByteArrayOutputStream;
020: import java.io.FileNotFoundException;
021: import java.io.IOException;
022: import java.io.OutputStream;
023:
024: /**
025: * A output stream writing to a ByteArrayOutputStream, until an OutputStream target is defined.
026: *
027: * @author huber@apache.org
028: * @author uv@upaya.co.uk
029: * @version CVS $Id: DelayedOutputStream.java 433543 2006-08-22 06:22:54Z crossley $
030: */
031: public class DelayedOutputStream extends OutputStream {
032: /**
033: * write to baos as long as fos member is still null,
034: * create a ByteArrayOutputStream only
035: */
036: private ByteArrayOutputStream baos;
037: /**
038: * If fos is defined write into fos, dump content of
039: * baos to fos first
040: */
041: private OutputStream fos;
042:
043: /**
044: * Constructor for the DelayedFileOutputStream object,
045: * create a ByteArrayOutputStream only
046: */
047: public DelayedOutputStream() {
048: baos = new ByteArrayOutputStream();
049: fos = null;
050: }
051:
052: /**
053: * Creates a file output stream to write to the file represented by the specified File object.
054: *
055: * @param outputStream The new fileOutputStream value
056: * @exception FileNotFoundException thrown if creating of FileOutputStream fails
057: */
058: public void setFileOutputStream(OutputStream outputStream)
059: throws FileNotFoundException {
060: if (fos == null) {
061: fos = outputStream;
062: }
063: }
064:
065: /**
066: * Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
067: * state of this stream
068: *
069: * @param b Description of Parameter
070: * @exception IOException thrown iff implicitly flush of baos to fos fails, or writing
071: * of baos, or fos fails
072: */
073: public void write(int b) throws IOException {
074: OutputStream os = getTargetOutputStream();
075: os.write(b);
076: }
077:
078: /**
079: * Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
080: * state of this stream
081: *
082: * @param b Description of Parameter
083: * @exception IOException thrown iff implicitly flush of baos to fos fails, or writing
084: * of baos, or fos fails
085: */
086: public void write(byte b[]) throws IOException {
087: OutputStream os = getTargetOutputStream();
088: os.write(b);
089: }
090:
091: /**
092: * Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
093: * state of this stream
094: *
095: * @param b Description of Parameter
096: * @param off Description of Parameter
097: * @param len Description of Parameter
098: * @exception IOException thrown iff implicitly flush of baos to fos fails, or writing
099: * of baos, or fos fails
100: */
101: public void write(byte b[], int off, int len) throws IOException {
102: OutputStream os = getTargetOutputStream();
103: os.write(b, off, len);
104: }
105:
106: /**
107: * Close ByteArrayOutputStrem, and FileOutputStream, depending on inner
108: * state of this stream
109: *
110: * @exception IOException thrown iff implicitly flush of baos to fos fails, or closing
111: * of baos, or fos fails
112: */
113: public void close() throws IOException {
114: IOException ioexception = null;
115:
116: getTargetOutputStream();
117:
118: // close baos
119: try {
120: if (baos != null) {
121: baos.close();
122: }
123: } catch (IOException ioe) {
124: ioexception = ioe;
125: } finally {
126: baos = null;
127: }
128:
129: // close fos
130: try {
131: if (fos != null) {
132: fos.close();
133: }
134: } catch (IOException ioe) {
135: if (ioexception == null) {
136: ioexception = ioe;
137: }
138: } finally {
139: fos = null;
140: }
141:
142: if (ioexception != null) {
143: throw ioexception;
144: }
145: }
146:
147: /**
148: * Flush ByteArrayOutputStrem, writing content to FileOutputStream,
149: * flush FileOutputStream
150: *
151: * @exception IOException thrown iff implicitly flush of baos to fos fails, or flushing
152: * of baos, or fos fails
153: */
154: public void flush() throws IOException {
155: IOException ioexception = null;
156:
157: // flush baos, writing to fos, if neccessary
158: getTargetOutputStream();
159:
160: // flush baos
161: try {
162: if (baos != null) {
163: baos.flush();
164: }
165: } catch (IOException ioe) {
166: ioexception = ioe;
167: }
168:
169: // flush fos
170: try {
171: if (fos != null) {
172: fos.flush();
173: }
174: } catch (IOException ioe) {
175: if (ioexception == null) {
176: ioexception = ioe;
177: }
178: }
179: if (ioexception != null) {
180: throw ioexception;
181: }
182: }
183:
184: /**
185: * Gets the targetOutputStream attribute of the DelayedFileOutputStream object
186: *
187: * @return The targetOutputStream value
188: * @exception IOException thrown iff implicitly flush of baos to fos fails
189: */
190: private OutputStream getTargetOutputStream() throws IOException {
191: if (baos != null && fos == null) {
192:
193: // no fos is defined, just write to baos in the mean time
194: return baos;
195: } else if (baos != null && fos != null) {
196: // fos is defined, flush boas to fos, and destroy baos
197: try {
198: baos.flush();
199: baos.writeTo(fos);
200: baos.close();
201: } finally {
202: baos = null;
203: }
204:
205: return fos;
206: } else if (baos == null && fos != null) {
207: // no more temporary baos writing, write directly to fos
208: return fos;
209: } else {
210: // neither baos, nor fos are valid
211: throw new IOException("No outputstream available!");
212: }
213: }
214:
215: /**
216: * Gets the size of the content of the current output stream
217: */
218: public int size() {
219: if (baos != null) {
220: return baos.size();
221: }
222: return 0;
223: }
224:
225: /**
226: * Return the contents of the stream as a byte array
227: */
228: public byte[] getContent() {
229: if (baos != null) {
230: return baos.toByteArray();
231: } else {
232: return null;
233: }
234: }
235: }
|