001: // FileFallbackByteArrayOutputStream.java
002: // -------------------------------------
003: // part of YACY
004: // (C) by Michael Peter Christen; mc@anomic.de
005: // first published on http://www.anomic.de
006: // Frankfurt, Germany, 2004
007: //
008: // This file ist contributed by Franz Brausze
009: //
010: // This program is free software; you can redistribute it and/or modify
011: // it under the terms of the GNU General Public License as published by
012: // the Free Software Foundation; either version 2 of the License, or
013: // (at your option) any later version.
014: //
015: // This program is distributed in the hope that it will be useful,
016: // but WITHOUT ANY WARRANTY; without even the implied warranty of
017: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
018: // GNU General Public License for more details.
019: //
020: // You should have received a copy of the GNU General Public License
021: // along with this program; if not, write to the Free Software
022: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023: //
024: // Using this software in any meaning (reading, learning, copying, compiling,
025: // running) means that you agree that the Author(s) is (are) not responsible
026: // for cost, loss of data or any harm that may be caused directly or indirectly
027: // by usage of this softare or this documentation. The usage of this software
028: // is on your own risk. The installation and usage (starting/running) of this
029: // software may allow other people or application to access your computer and
030: // any attached devices and is highly dependent on the configuration of the
031: // software which must be done by the user of the software; the author(s) is
032: // (are) also not responsible for proper configuration and usage of the
033: // software, even if provoked by documentation provided together with
034: // the software.
035: //
036: // Any changes to this file according to the GPL as documented in the file
037: // gpl.txt aside this file in the shipment you received can be done to the
038: // lines that follows this copyright notice here, but changes must not be
039: // done inside the copyright notive above. A re-distribution must contain
040: // the intact and unchanged copyright notice.
041: // Contributions and changes to the program code must be marked as such.
042:
043: package de.anomic.server;
044:
045: import java.io.BufferedInputStream;
046: import java.io.BufferedOutputStream;
047: import java.io.ByteArrayInputStream;
048: import java.io.ByteArrayOutputStream;
049: import java.io.File;
050: import java.io.FileInputStream;
051: import java.io.FileOutputStream;
052: import java.io.IOException;
053: import java.io.InputStream;
054: import java.io.OutputStream;
055:
056: public class serverCachedFileOutputStream extends ByteArrayOutputStream {
057:
058: protected File fallbackFile;
059: protected long fallbackSize;
060: protected boolean buffered;
061:
062: protected long size = 0;
063: protected boolean isFallback = false;
064: protected OutputStream fallback = null;
065:
066: public serverCachedFileOutputStream(long fallbackSize)
067: throws IOException {
068: this (fallbackSize, null, true, 32);
069: }
070:
071: public serverCachedFileOutputStream(long fallbackSize,
072: File fallback, boolean buffered) throws IOException {
073: this (fallbackSize, fallback, buffered, 32);
074: }
075:
076: public serverCachedFileOutputStream(long fallbackSize,
077: File fallback, boolean buffered, long size)
078: throws IOException {
079: this .fallbackSize = fallbackSize;
080: this .fallbackFile = (fallback == null) ? File.createTempFile(
081: serverCachedFileOutputStream.class.getName(), Long
082: .toString(System.currentTimeMillis()))
083: : fallback;
084: this .buffered = buffered;
085: checkFallback(size);
086: }
087:
088: public serverCachedFileOutputStream(long fallbackSize,
089: File fallback, boolean buffered, byte[] data)
090: throws IOException {
091: this (fallbackSize, fallback, buffered, 0);
092: super .buf = data;
093: super .count = data.length;
094: checkFallback(this .size = data.length);
095: }
096:
097: protected boolean checkFallback(long size) {
098: if (size > this .fallbackSize)
099: try {
100: fallback();
101: return true;
102: } catch (IOException e) {
103: throw new RuntimeException(
104: "error falling back to file", e);
105: }
106: else {
107: return false;
108: }
109: }
110:
111: public void fallback() throws IOException {
112: if (this .isFallback)
113: return;
114: this .isFallback = true;
115: if (!this .fallbackFile.exists()) {
116: this .fallbackFile.createNewFile();
117: } else if (this .fallbackFile.isDirectory()) {
118: throw new IOException("cannot write on a directory");
119: }
120: OutputStream os = new FileOutputStream(this .fallbackFile);
121: this .fallback = (this .buffered) ? new BufferedOutputStream(os)
122: : os;
123: serverFileUtils.copy(new ByteArrayInputStream(super .buf),
124: this .fallback);
125: super .buf = new byte[0];
126: super .count = 0;
127: super .reset();
128: }
129:
130: public boolean isFallback() {
131: return this .isFallback;
132: }
133:
134: public void write(int b) {
135: if (checkFallback(++this .size))
136: try {
137: this .fallback.write(b);
138: } catch (IOException e) {
139: throw new RuntimeException("error writing to fallback",
140: e);
141: }
142: else {
143: super .write(b);
144: }
145: }
146:
147: public void write(byte[] b, int off, int len) {
148: if (checkFallback(this .size += len))
149: try {
150: this .fallback.write(b, off, len);
151: } catch (IOException e) {
152: throw new RuntimeException("error writing to fallback",
153: e);
154: }
155: else {
156: super .write(b, off, len);
157: }
158: }
159:
160: public void close() throws IOException {
161: if (this .fallback != null)
162: this .fallback.close();
163: super .close();
164: }
165:
166: public InputStream getContent() throws IOException {
167: close();
168: if (this .isFallback) {
169: InputStream is = new FileInputStream(this .fallbackFile);
170: return (this .buffered) ? new BufferedInputStream(is) : is;
171: } else {
172: return new ByteArrayInputStream(this .buf);
173: }
174: }
175:
176: public byte[] getContentBAOS() {
177: if (this .isFallback)
178: throw new RuntimeException(
179: "underlying ByteArrayOutputStream not available, already fell back to file");
180: return super .buf;
181: }
182:
183: public File getContentFile() {
184: if (!this .isFallback)
185: throw new RuntimeException(
186: "haven't fallen back yet, fallback file has no content");
187: return this .fallbackFile;
188: }
189:
190: public long getLength() {
191: return this.size;
192: }
193: }
|