001: /*
002: * Author: Chris Seguin
003: *
004: * This software has been developed under the copyleft
005: * rules of the GNU General Public License. Please
006: * consult the GNU General Public License for more
007: * details about use and distribution of this software.
008: */
009: package org.acm.seguin.io;
010:
011: import java.io.File;
012: import java.io.OutputStream;
013: import java.io.FileOutputStream;
014: import java.io.IOException;
015: import org.acm.seguin.util.FileSettings;
016:
017: /**
018: * To the user of this object, it appears that the file is written in place.
019: *
020: *@author Chris Seguin
021: *@author <a href="JRefactory@ladyshot.demon.co.uk">Mike Atkinson</a>
022: *@version $Id: InplaceOutputStream.java,v 1.6 2003/09/01 00:25:31 mikeatkinson Exp $
023: *@date May 12, 1999
024: */
025: public class InplaceOutputStream extends OutputStream {
026: // Instance Variables
027: private File finalDestination;
028: private File temporary;
029: private FileOutputStream out;
030:
031: /**
032: * Creates an InplaceOutputStream
033: *
034: *@param dest the output file location
035: *@exception IOException throws an IOException
036: */
037: public InplaceOutputStream(File dest) throws IOException {
038: finalDestination = dest;
039:
040: String parent = dest.getPath();
041: if ((parent != null)
042: && attempt(parent + File.separator + "inplace")) {
043: // Things have worked out!
044: } else if (attempt("." + File.separator + "inplace")) {
045: // Things have worked out!
046: } else if (attempt(new File(FileSettings
047: .getRefactorySettingsRoot(), "inplace").toString())) {
048: } else {
049: throw new IOException("Unable to create the output file!");
050: }
051: }
052:
053: /**
054: * Closes the file
055: *
056: *@exception IOException throws an IOException
057: */
058: public void close() throws IOException {
059: if (out == null) {
060: return;
061: }
062:
063: // Close the file
064: out.close();
065:
066: // Copy it inplace
067: if (temporary.exists() && (temporary.length() > 0)) {
068: (new FileCopy(temporary, finalDestination, false)).run();
069: }
070:
071: // Delete the temporary file
072: temporary.delete();
073:
074: // Note that we are done
075: out = null;
076: }
077:
078: /**
079: * Flush the file
080: *
081: *@exception IOException throws an IOException
082: */
083: public void flush() throws IOException {
084: if (out == null) {
085: return;
086: }
087:
088: out.flush();
089: }
090:
091: /**
092: * Write a byte to the file
093: *
094: *@param b the byte to be written
095: *@exception IOException throws an IOException
096: */
097: public void write(int b) throws IOException {
098: if (out == null) {
099: return;
100: }
101:
102: out.write(b);
103: }
104:
105: /**
106: * Write a byte array to the file
107: *
108: *@param b the byte array to be written
109: *@exception IOException throws an IOException
110: */
111: public void write(byte b[]) throws IOException {
112: if (out == null) {
113: return;
114: }
115:
116: out.write(b);
117: }
118:
119: /**
120: * Write a byte array to the file
121: *
122: *@param b the byte array to be written
123: *@param off the offset into the array
124: *@param len the number of bytes to write
125: *@exception IOException throws an IOException
126: */
127: public void write(byte b[], int off, int len) throws IOException {
128: if (out == null) {
129: return;
130: }
131:
132: out.write(b, off, len);
133: }
134:
135: /**
136: * Make sure to clean up after itself
137: */
138: protected void finalize() {
139: if (out == null) {
140: return;
141: }
142:
143: try {
144: close();
145: } catch (IOException ioe) {
146: }
147: }
148:
149: /**
150: * Description of the Method
151: *
152: *@param prefix Description of Parameter
153: *@param suffix Description of Parameter
154: *@return Description of the Returned Value
155: */
156: private File createTempFile(String prefix, String suffix) {
157: for (int ndx = 0; ndx < 1024; ndx++) {
158: double number = Math.random() * 1024 * 1024;
159: long rounded = Math.round(number);
160:
161: File possible = new File(prefix + rounded + suffix);
162: if (!possible.exists()) {
163: return possible;
164: }
165: }
166:
167: return null;
168: }
169:
170: /** Attempts to determine if the file can be used for output
171: *@param filepath the file to open
172: *@return true if it worked
173: */
174: private boolean attempt(String filepath) {
175: try {
176: temporary = createTempFile(filepath, ".java");
177: temporary.delete();
178: if (temporary.exists())
179: return false;
180:
181: out = new FileOutputStream(temporary);
182: } catch (IOException ioe) {
183: return false;
184: }
185: return true;
186: }
187: }
|