package com.scaleunlimited.cascading.local;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import cascading.tap.Tap;
import cascading.tap.TapException;
public class DirectoryFileOutputStream extends FileOutputStream {
private File _file;
public DirectoryFileOutputStream(String path, boolean append) throws FileNotFoundException {
this(null, path, append);
}
public DirectoryFileOutputStream(Tap parent, String path, boolean append) throws FileNotFoundException {
super(prepare(parent, path), append);
_file = getFile(parent, path);
}
public String asDirectory() throws IOException {
// We need to close down the current file, delete it, and return back the
close();
if (!_file.delete()) {
throw new IOException("Can't delete output file: " + _file);
}
return _file.getAbsolutePath();
}
private static String prepare(Tap parent, String path) {
// ignore the output. will catch the failure downstream if any.
// not ignoring the output causes race conditions with other systems
// writing to the same directory.
File file = getFile(parent, path);
File parentFile = file.getAbsoluteFile().getParentFile();
if (parentFile != null && parentFile.exists() && parentFile.isFile()) {
throw new TapException("cannot create parent directory, it already exists as a file: " + parentFile.getAbsolutePath());
}
// don't test for success, just fighting a race condition otherwise
// will get caught downstream
if (parentFile != null) {
parentFile.mkdirs();
}
return file.getAbsolutePath();
}
private static File getFile(Tap parent, String path) {
if (parent == null) {
return new File(path);
} else {
return new File(parent.getIdentifier(), path);
}
}
}