final String parentDir = FileSystemPathUtil.getParentDir(filePath);
final String name = FileSystemPathUtil.getName(filePath);
if (!isFolder(parentDir)) {
throw new FileSystemException("path not found: " + parentDir);
}
if (isFolder(filePath)) {
throw new FileSystemException("path denotes folder: " + filePath);
}
try {
TransientFileFactory fileFactory = TransientFileFactory.getInstance();
final File tmpFile = fileFactory.createTransientFile("bin", null, null);
// @todo FIXME use java.sql.Blob
if (isFile(filePath)) {
// file entry exists, spool contents to temp file first
InputStream in = getInputStream(filePath);
OutputStream out = new FileOutputStream(tmpFile);
try {
int read;
byte[] ba = new byte[8192];
while ((read = in.read(ba, 0, ba.length)) != -1) {
out.write(ba, 0, read);
}
} finally {
out.close();
in.close();
}
}
return new RandomAccessOutputStream() {
private final RandomAccessFile raf =
new RandomAccessFile(tmpFile, "rw");
public void close() throws IOException {
raf.close();
PreparedStatement stmt = null;
InputStream in = null;
Blob blob = null;
try {
if (isFile(filePath)) {
stmt = updateDataStmt;
synchronized (stmt) {
long length = tmpFile.length();
in = new FileInputStream(tmpFile);
blob = createTemporaryBlob(in);
stmt.setBlob(1, blob);
stmt.setLong(2, System.currentTimeMillis());
stmt.setLong(3, length);
stmt.setString(4, parentDir);
stmt.setString(5, name);
stmt.executeUpdate();
}
} else {
stmt = insertFileStmt;
stmt.setString(1, parentDir);
stmt.setString(2, name);
long length = tmpFile.length();
in = new FileInputStream(tmpFile);
blob = createTemporaryBlob(in);
stmt.setBlob(3, blob);
stmt.setLong(4, System.currentTimeMillis());
stmt.setLong(5, length);
stmt.executeUpdate();
}
} catch (Exception e) {
throw new IOException(e.getMessage());
} finally {
if (stmt != null) {
resetStatement(stmt);
}
if (blob != null) {
try {
freeTemporaryBlob(blob);
} catch (Exception e1) {
}
}
if (in != null) {
try {
in.close();
} catch (Exception e1) {
}
}
// temp file can now safely be removed
tmpFile.delete();
}
}
public void seek(long position) throws IOException {
raf.seek(position);
}
public void write(int b) throws IOException {
raf.write(b);
}
public void flush() /*throws IOException*/ {
// nop
}
public void write(byte[] b) throws IOException {
raf.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
raf.write(b, off, len);
}
};
} catch (Exception e) {
String msg = "failed to open output stream to file: " + filePath;
log.error(msg, e);
throw new FileSystemException(msg, e);
}
}